69 #include "llvm/IR/IntrinsicsPowerPC.h"
102 using namespace llvm;
104 #define DEBUG_TYPE "ppc-lowering"
110 cl::desc(
"disable setting the node scheduling preference to ILP on PPC"),
cl::Hidden);
125 "ppc-quadword-atomics",
131 STATISTIC(ShufflesHandledWithVPERM,
"Number of shuffles lowered to a VPERM");
132 STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
149 initializeAddrModeMap();
152 bool isPPC64 = Subtarget.
isPPC64();
216 if (!Subtarget.
hasSPE()) {
225 for (
MVT VT : ScalarIntVTs) {
235 if (isPPC64 || Subtarget.
hasFPCVT()) {
344 if (!Subtarget.
hasSPE()) {
515 if (
TM.Options.UnsafeFPMath) {
739 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
968 if (
TM.Options.UnsafeFPMath) {
1205 }
else if (Subtarget.
hasVSX()) {
1274 if (Subtarget.
hasMMA()) {
1484 void PPCTargetLowering::initializeAddrModeMap() {
1535 if (MaxAlign == MaxMaxAlign)
1537 if (
VectorType *VTy = dyn_cast<VectorType>(Ty)) {
1538 if (MaxMaxAlign >= 32 &&
1539 VTy->getPrimitiveSizeInBits().getFixedSize() >= 256)
1540 MaxAlign =
Align(32);
1541 else if (VTy->getPrimitiveSizeInBits().getFixedSize() >= 128 &&
1543 MaxAlign =
Align(16);
1544 }
else if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
1547 if (EltAlign > MaxAlign)
1548 MaxAlign = EltAlign;
1549 }
else if (
StructType *STy = dyn_cast<StructType>(Ty)) {
1550 for (
auto *EltTy : STy->elements()) {
1553 if (EltAlign > MaxAlign)
1554 MaxAlign = EltAlign;
1555 if (MaxAlign == MaxMaxAlign)
1570 return Alignment.
value();
1578 return Subtarget.
hasSPE();
1600 return "PPCISD::FP_TO_UINT_IN_VSR,";
1602 return "PPCISD::FP_TO_SINT_IN_VSR";
1606 return "PPCISD::FTSQRT";
1608 return "PPCISD::FSQRT";
1613 return "PPCISD::XXSPLTI_SP_TO_DP";
1615 return "PPCISD::XXSPLTI32DX";
1637 return "PPCISD::CALL_RM";
1639 return "PPCISD::CALL_NOP_RM";
1641 return "PPCISD::CALL_NOTOC_RM";
1646 return "PPCISD::BCTRL_RM";
1648 return "PPCISD::BCTRL_LOAD_TOC_RM";
1660 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1662 return "PPCISD::ANDI_rec_1_EQ_BIT";
1664 return "PPCISD::ANDI_rec_1_GT_BIT";
1679 return "PPCISD::ST_VSR_SCAL_INT";
1705 return "PPCISD::PADDI_DTPREL";
1722 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1724 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1734 return "PPCISD::STRICT_FADDRTZ";
1736 return "PPCISD::STRICT_FCTIDZ";
1738 return "PPCISD::STRICT_FCTIWZ";
1740 return "PPCISD::STRICT_FCTIDUZ";
1742 return "PPCISD::STRICT_FCTIWUZ";
1744 return "PPCISD::STRICT_FCFID";
1746 return "PPCISD::STRICT_FCFIDU";
1748 return "PPCISD::STRICT_FCFIDS";
1750 return "PPCISD::STRICT_FCFIDUS";
1776 return CFP->getValueAPF().isZero();
1780 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(
CP->getConstVal()))
1781 return CFP->getValueAPF().isZero();
1789 return Op < 0 ||
Op == Val;
1801 if (ShuffleKind == 0) {
1804 for (
unsigned i = 0; i != 16; ++i)
1807 }
else if (ShuffleKind == 2) {
1810 for (
unsigned i = 0; i != 16; ++i)
1813 }
else if (ShuffleKind == 1) {
1814 unsigned j = IsLE ? 0 : 1;
1815 for (
unsigned i = 0; i != 8; ++i)
1832 if (ShuffleKind == 0) {
1835 for (
unsigned i = 0; i != 16; i += 2)
1839 }
else if (ShuffleKind == 2) {
1842 for (
unsigned i = 0; i != 16; i += 2)
1846 }
else if (ShuffleKind == 1) {
1847 unsigned j = IsLE ? 0 : 2;
1848 for (
unsigned i = 0; i != 8; i += 2)
1874 if (ShuffleKind == 0) {
1877 for (
unsigned i = 0; i != 16; i += 4)
1883 }
else if (ShuffleKind == 2) {
1886 for (
unsigned i = 0; i != 16; i += 4)
1892 }
else if (ShuffleKind == 1) {
1893 unsigned j = IsLE ? 0 : 4;
1894 for (
unsigned i = 0; i != 8; i += 4)
1911 unsigned LHSStart,
unsigned RHSStart) {
1914 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1915 "Unsupported merge size!");
1917 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1918 for (
unsigned j = 0; j != UnitSize; ++j) {
1920 LHSStart+j+i*UnitSize) ||
1922 RHSStart+j+i*UnitSize))
1937 if (ShuffleKind == 1)
1939 else if (ShuffleKind == 2)
1944 if (ShuffleKind == 1)
1946 else if (ShuffleKind == 0)
1962 if (ShuffleKind == 1)
1964 else if (ShuffleKind == 2)
1969 if (ShuffleKind == 1)
1971 else if (ShuffleKind == 0)
2021 unsigned RHSStartValue) {
2025 for (
unsigned i = 0; i < 2; ++i)
2026 for (
unsigned j = 0; j < 4; ++j)
2028 i*RHSStartValue+j+IndexOffset) ||
2030 i*RHSStartValue+j+IndexOffset+8))
2052 unsigned indexOffset = CheckEven ? 4 : 0;
2053 if (ShuffleKind == 1)
2055 else if (ShuffleKind == 2)
2061 unsigned indexOffset = CheckEven ? 0 : 4;
2062 if (ShuffleKind == 1)
2064 else if (ShuffleKind == 0)
2087 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2090 if (i == 16)
return -1;
2095 if (ShiftAmt < i)
return -1;
2100 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2102 for (++i; i != 16; ++i)
2105 }
else if (ShuffleKind == 1) {
2107 for (++i; i != 16; ++i)
2114 ShiftAmt = 16 - ShiftAmt;
2124 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2128 if (
N->getMaskElt(0) % EltSize != 0)
2133 unsigned ElementBase =
N->getMaskElt(0);
2136 if (ElementBase >= 16)
2141 for (
unsigned i = 1; i != EltSize; ++i)
2142 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2145 for (
unsigned i = EltSize,
e = 16; i !=
e; i += EltSize) {
2146 if (
N->getMaskElt(i) < 0)
continue;
2147 for (
unsigned j = 0; j != EltSize; ++j)
2148 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
2166 "Unexpected element width.");
2167 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2169 unsigned NumOfElem = 16 /
Width;
2170 unsigned MaskVal[16];
2171 for (
unsigned i = 0; i < NumOfElem; ++i) {
2172 MaskVal[0] =
N->getMaskElt(i *
Width);
2173 if ((StepLen == 1) && (MaskVal[0] %
Width)) {
2175 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) %
Width)) {
2179 for (
unsigned int j = 1; j <
Width; ++j) {
2180 MaskVal[j] =
N->getMaskElt(i *
Width + j);
2181 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2191 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2196 unsigned M0 =
N->getMaskElt(0) / 4;
2197 unsigned M1 =
N->getMaskElt(4) / 4;
2198 unsigned M2 =
N->getMaskElt(8) / 4;
2199 unsigned M3 =
N->getMaskElt(12) / 4;
2200 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2201 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2206 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2207 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2208 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2209 InsertAtByte = IsLE ? 12 : 0;
2214 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2215 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2216 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2217 InsertAtByte = IsLE ? 8 : 4;
2222 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2223 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2224 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2225 InsertAtByte = IsLE ? 4 : 8;
2230 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2231 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2232 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2233 InsertAtByte = IsLE ? 0 : 12;
2240 if (
N->getOperand(1).isUndef()) {
2243 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2244 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2245 InsertAtByte = IsLE ? 12 : 0;
2248 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2249 InsertAtByte = IsLE ? 8 : 4;
2252 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2253 InsertAtByte = IsLE ? 4 : 8;
2256 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2257 InsertAtByte = IsLE ? 0 : 12;
2266 bool &Swap,
bool IsLE) {
2273 unsigned M0 =
N->getMaskElt(0) / 4;
2274 unsigned M1 =
N->getMaskElt(4) / 4;
2275 unsigned M2 =
N->getMaskElt(8) / 4;
2276 unsigned M3 =
N->getMaskElt(12) / 4;
2280 if (
N->getOperand(1).isUndef()) {
2281 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2282 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2285 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2291 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2295 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2300 ShiftElts = (8 -
M0) % 8;
2301 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2306 ShiftElts = (4 -
M0) % 4;
2311 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2316 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2333 for (
int i = 0; i < 16; i +=
Width)
2334 if (
N->getMaskElt(i) != i +
Width - 1)
2365 bool &Swap,
bool IsLE) {
2372 unsigned M0 =
N->getMaskElt(0) / 8;
2373 unsigned M1 =
N->getMaskElt(8) / 8;
2374 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2378 if (
N->getOperand(1).isUndef()) {
2379 if ((
M0 |
M1) < 2) {
2380 DM = IsLE ? (((~
M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2388 if (
M0 > 1 &&
M1 < 2) {
2390 }
else if (M0 < 2 && M1 > 1) {
2398 DM = (((~
M1) & 1) << 1) + ((~
M0) & 1);
2401 if (M0 < 2 && M1 > 1) {
2403 }
else if (
M0 > 1 &&
M1 < 2) {
2411 DM = (
M0 << 1) + (
M1 & 1);
2425 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2441 unsigned EltSize = 16/
N->getNumOperands();
2442 if (EltSize < ByteSize) {
2443 unsigned Multiple = ByteSize/EltSize;
2445 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2448 for (
unsigned i = 0,
e =
N->getNumOperands(); i !=
e; ++i) {
2449 if (
N->getOperand(i).isUndef())
continue;
2451 if (!isa<ConstantSDNode>(
N->getOperand(i)))
return SDValue();
2453 if (!UniquedVals[i&(Multiple-1)].getNode())
2454 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2455 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2465 bool LeadingZero =
true;
2466 bool LeadingOnes =
true;
2467 for (
unsigned i = 0; i != Multiple-1; ++i) {
2468 if (!UniquedVals[i].getNode())
continue;
2475 if (!UniquedVals[Multiple-1].getNode())
2477 int Val = cast<ConstantSDNode>(UniquedVals[Multiple-1])->getZExtValue();
2482 if (!UniquedVals[Multiple-1].getNode())
2484 int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSExtValue();
2493 for (
unsigned i = 0,
e =
N->getNumOperands(); i !=
e; ++i) {
2494 if (
N->getOperand(i).isUndef())
continue;
2496 OpVal =
N->getOperand(i);
2497 else if (OpVal !=
N->getOperand(i))
2503 unsigned ValSizeInBytes = EltSize;
2506 Value = CN->getZExtValue();
2508 assert(CN->getValueType(0) ==
MVT::f32 &&
"Only one legal FP vector type!");
2515 if (ValSizeInBytes < ByteSize)
return SDValue();
2526 if (MaskVal == 0)
return SDValue();
2529 if (SignExtend32<5>(MaskVal) == MaskVal)
2543 if (!isa<ConstantSDNode>(
N))
2546 Imm = (int16_t)cast<ConstantSDNode>(
N)->getZExtValue();
2548 return Imm == (int32_t)cast<ConstantSDNode>(
N)->getZExtValue();
2550 return Imm == (int64_t)cast<ConstantSDNode>(
N)->getZExtValue();
2568 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2577 if (
MemSDNode *Memop = dyn_cast<MemSDNode>(U)) {
2578 if (Memop->getMemoryVT() ==
MVT::f64) {
2579 Base =
N.getOperand(0);
2592 if (!isa<ConstantSDNode>(
N))
2595 Imm = (int64_t)cast<ConstantSDNode>(
N)->getZExtValue();
2596 return isInt<34>(Imm);
2623 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2628 Base =
N.getOperand(0);
2631 }
else if (
N.getOpcode() ==
ISD::OR) {
2633 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2645 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2646 Base =
N.getOperand(0);
2717 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2723 Base =
N.getOperand(0);
2726 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2728 assert(!cast<ConstantSDNode>(
N.getOperand(1).getOperand(1))->getZExtValue()
2729 &&
"Cannot handle constant offsets yet!");
2730 Disp =
N.getOperand(1).getOperand(0);
2735 Base =
N.getOperand(0);
2738 }
else if (
N.getOpcode() ==
ISD::OR) {
2741 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2751 dyn_cast<FrameIndexSDNode>(
N.getOperand(0))) {
2755 Base =
N.getOperand(0);
2768 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2771 CN->getValueType(0));
2776 if ((CN->getValueType(0) ==
MVT::i32 ||
2777 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2778 (!EncodingAlignment ||
2779 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2780 int Addr = (int)CN->getZExtValue();
2821 Base =
N.getOperand(0);
2837 Base =
N.getOperand(0);
2870 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2871 Base =
N.getOperand(0);
2884 Ty *PCRelCand = dyn_cast<Ty>(
N);
2896 if (isValidPCRelNode<ConstantPoolSDNode>(
N) ||
2897 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
2898 isValidPCRelNode<JumpTableSDNode>(
N) ||
2899 isValidPCRelNode<BlockAddressSDNode>(
N))
2915 EVT MemVT =
LD->getMemoryVT();
2922 if (!
ST.hasP8Vector())
2927 if (!
ST.hasP9Vector())
2940 if (UI.getUse().get().getResNo() == 0 &&
2962 Ptr =
LD->getBasePtr();
2963 VT =
LD->getMemoryVT();
2964 Alignment =
LD->getAlignment();
2966 Ptr =
ST->getBasePtr();
2967 VT =
ST->getMemoryVT();
2968 Alignment =
ST->getAlignment();
2991 if (isa<FrameIndexSDNode>(
Base) || isa<RegisterSDNode>(
Base))
2994 SDValue Val = cast<StoreSDNode>(
N)->getValue();
3024 isa<ConstantSDNode>(
Offset))
3039 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3081 const bool Is64Bit = Subtarget.
isPPC64();
3096 EVT PtrVT =
Op.getValueType();
3112 return getTOCEntry(DAG,
SDLoc(
CP), GA);
3115 unsigned MOHiFlag, MOLoFlag;
3122 return getTOCEntry(DAG,
SDLoc(
CP), GA);
3182 EVT PtrVT =
Op.getValueType();
3200 return getTOCEntry(DAG,
SDLoc(
JT), GA);
3203 unsigned MOHiFlag, MOLoFlag;
3210 return getTOCEntry(DAG,
SDLoc(GA), GA);
3220 EVT PtrVT =
Op.getValueType();
3239 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3248 unsigned MOHiFlag, MOLoFlag;
3259 return LowerGlobalTLSAddressAIX(
Op, DAG);
3261 return LowerGlobalTLSAddressLinux(
Op, DAG);
3285 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3286 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3304 bool is64bit = Subtarget.
isPPC64();
3352 if (!
TM.isPositionIndependent())
3411 PtrVT, GOTPtr, TGA, TGA);
3413 PtrVT, TLSAddr, TGA);
3422 EVT PtrVT =
Op.getValueType();
3448 return getTOCEntry(DAG,
DL, GA);
3451 unsigned MOHiFlag, MOLoFlag;
3459 return getTOCEntry(DAG,
DL, GA);
3471 bool IsStrict =
Op->isStrictFPOpcode();
3473 cast<CondCodeSDNode>(
Op.getOperand(IsStrict ? 3 : 2))->get();
3477 EVT LHSVT =
LHS.getValueType();
3483 "SETCC for f128 is already legal under Power9!");
3494 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3507 int ShuffV[] = {1, 0, 3, 2};
3529 if (
C->isAllOnes() ||
C->isZero())
3539 EVT VT =
Op.getValueType();
3548 EVT VT = Node->getValueType(0);
3550 SDValue InChain = Node->getOperand(0);
3551 SDValue VAListPtr = Node->getOperand(1);
3552 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
3593 InChain = OverflowArea.
getValue(1);
3639 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3646 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3661 return Op.getOperand(0);
3670 "Expecting Inline ASM node.");
3679 unsigned NumOps =
Op.getNumOperands();
3680 if (
Op.getOperand(NumOps - 1).getValueType() ==
MVT::Glue)
3685 unsigned Flags = cast<ConstantSDNode>(
Op.getOperand(i))->getZExtValue();
3700 for (; NumVals; --NumVals, ++i) {
3701 Register Reg = cast<RegisterSDNode>(
Op.getOperand(i))->getReg();
3702 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3727 bool isPPC64 = (PtrVT ==
MVT::i64);
3731 TargetLowering::ArgListEntry Entry;
3733 Entry.Ty = IntPtrTy;
3734 Entry.Node = Trmp;
Args.push_back(Entry);
3737 Entry.Node = DAG.
getConstant(isPPC64 ? 48 : 40, dl,
3739 Args.push_back(Entry);
3741 Entry.Node = FPtr;
Args.push_back(Entry);
3742 Entry.Node = Nest;
Args.push_back(Entry);
3746 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3750 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3751 return CallResult.second;
3765 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
3766 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3801 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3810 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
3825 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3828 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3830 nextOffset += FrameOffset;
3831 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
3834 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
3840 static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
3841 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
3842 PPC::F11, PPC::F12, PPC::F13};
3847 unsigned PtrByteSize) {
3855 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
3864 unsigned PtrByteSize) {
3865 Align Alignment(PtrByteSize);
3872 Alignment =
Align(16);
3877 if (BVAlign > PtrByteSize) {
3878 if (BVAlign.value() % PtrByteSize != 0)
3880 "ByVal alignment is not a multiple of the pointer size");
3882 Alignment = BVAlign;
3905 unsigned PtrByteSize,
unsigned LinkageSize,
3906 unsigned ParamAreaSize,
unsigned &ArgOffset,
3907 unsigned &AvailableFPRs,
3908 unsigned &AvailableVRs) {
3909 bool UseMemory =
false;
3914 ArgOffset =
alignTo(ArgOffset, Alignment);
3917 if (ArgOffset >= LinkageSize + ParamAreaSize)
3923 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
3926 if (ArgOffset > LinkageSize + ParamAreaSize)
3933 if (AvailableFPRs > 0) {
3941 if (AvailableVRs > 0) {
3953 unsigned NumBytes) {
3957 SDValue PPCTargetLowering::LowerFormalArguments(
3962 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg,
Ins, dl, DAG,
3965 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg,
Ins, dl, DAG,
3968 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg,
Ins, dl, DAG,
3972 SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4014 const Align PtrAlign(4);
4023 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4025 CCInfo.PreAnalyzeFormalArguments(
Ins);
4028 CCInfo.clearWasPPCF128();
4030 for (
unsigned i = 0,
e = ArgLocs.
size(); i !=
e; ++i) {
4043 RC = &PPC::GPRCRegClass;
4047 RC = &PPC::VSSRCRegClass;
4048 else if (Subtarget.
hasSPE())
4049 RC = &PPC::GPRCRegClass;
4051 RC = &PPC::F4RCRegClass;
4055 RC = &PPC::VSFRCRegClass;
4056 else if (Subtarget.
hasSPE())
4058 RC = &PPC::GPRCRegClass;
4060 RC = &PPC::F8RCRegClass;
4065 RC = &PPC::VRRCRegClass;
4068 RC = &PPC::VRRCRegClass;
4072 RC = &PPC::VRRCRegClass;
4080 assert(i + 1 <
e &&
"No second half of double precision argument");
4108 ArgOffset += ArgSize - ObjSize;
4126 CCByValInfo.AllocateStack(CCInfo.getNextStackOffset(), PtrAlign);
4131 unsigned MinReservedArea = CCByValInfo.getNextStackOffset();
4132 MinReservedArea =
std::max(MinReservedArea, LinkageSize);
4149 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4154 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4166 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4171 CCInfo.getNextStackOffset(),
true));
4180 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
4184 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4199 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4203 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4216 if (!MemOps.
empty())
4227 const SDLoc &dl)
const {
4238 SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4251 "fastcc not supported on varargs functions");
4257 unsigned PtrByteSize = 8;
4261 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4262 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4266 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4279 bool HasParameterArea = !isELFv2ABI || isVarArg;
4280 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4281 unsigned NumBytes = LinkageSize;
4282 unsigned AvailableFPRs = Num_FPR_Regs;
4283 unsigned AvailableVRs = Num_VR_Regs;
4284 for (
unsigned i = 0,
e =
Ins.size(); i !=
e; ++i) {
4289 PtrByteSize, LinkageSize, ParamAreaSize,
4290 NumBytes, AvailableFPRs, AvailableVRs))
4291 HasParameterArea =
true;
4298 unsigned ArgOffset = LinkageSize;
4299 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4302 unsigned CurArgIdx = 0;
4303 for (
unsigned ArgNo = 0,
e =
Ins.size(); ArgNo !=
e; ++ArgNo) {
4305 bool needsLoad =
false;
4306 EVT ObjectVT =
Ins[ArgNo].VT;
4307 EVT OrigVT =
Ins[ArgNo].ArgVT;
4309 unsigned ArgSize = ObjSize;
4311 if (
Ins[ArgNo].isOrigArg()) {
4312 std::advance(FuncArg,
Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4313 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4318 unsigned CurArgOffset;
4320 auto ComputeArgOffset = [&]() {
4324 ArgOffset =
alignTo(ArgOffset, Alignment);
4325 CurArgOffset = ArgOffset;
4332 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4333 GPR_idx =
std::min(GPR_idx, Num_GPR_Regs);
4339 assert(
Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4346 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4368 if (HasParameterArea ||
4369 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4376 if (ObjSize < PtrByteSize) {
4380 if (!isLittleEndian) {
4386 if (GPR_idx != Num_GPR_Regs) {
4398 ArgOffset += PtrByteSize;
4407 for (
unsigned j = 0; j < ArgSize; j += PtrByteSize) {
4408 if (GPR_idx == Num_GPR_Regs)
4424 ArgOffset += ArgSize;
4439 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4447 if (GPR_idx != Num_GPR_Regs) {
4455 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4461 ArgSize = PtrByteSize;
4472 if (FPR_idx != Num_FPR_Regs) {
4478 ? &PPC::VSSRCRegClass
4479 : &PPC::F4RCRegClass);
4482 ? &PPC::VSFRCRegClass
4483 : &PPC::F8RCRegClass);
4499 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4518 ArgOffset += ArgSize;
4520 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4534 if (VR_idx != Num_VR_Regs) {
4551 if (ObjSize < ArgSize && !isLittleEndian)
4552 CurArgOffset += ArgSize - ObjSize;
4562 unsigned MinReservedArea;
4563 if (HasParameterArea)
4564 MinReservedArea =
std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4566 MinReservedArea = LinkageSize;
4583 int Depth = ArgOffset;
4592 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4593 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4605 if (!MemOps.
empty())
4614 unsigned ParamSize) {
4616 if (!isTailCall)
return 0;
4620 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4622 if (SPDiff < FI->getTailCallSPDelta())
4637 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4653 if (!
TM.shouldAssumeDSOLocal(*Caller->getParent(), GV))
4659 const Function *
F = dyn_cast<Function>(GV);
4660 const GlobalAlias *Alias = dyn_cast<GlobalAlias>(GV);
4665 F = dyn_cast<Function>(GlobalObj);
4698 if (
TM.getFunctionSections() || GV->
hasComdat() || Caller->hasComdat() ||
4701 if (
const auto *
F = dyn_cast<Function>(GV)) {
4702 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4714 const unsigned PtrByteSize = 8;
4718 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4719 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4723 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4727 const unsigned NumFPRs = 13;
4729 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4731 unsigned NumBytes = LinkageSize;
4732 unsigned AvailableFPRs = NumFPRs;
4733 unsigned AvailableVRs = NumVRs;
4736 if (
Param.Flags.isNest())
continue;
4739 LinkageSize, ParamAreaSize, NumBytes,
4740 AvailableFPRs, AvailableVRs))
4751 auto CalleeArgEnd = CB.
arg_end();
4754 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4755 const Value* CalleeArg = *CalleeArgIter;
4756 const Value* CallerArg = &(*CallerArgIter);
4757 if (CalleeArg == CallerArg)
4765 isa<UndefValue>(CalleeArg))
4783 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4793 bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4799 if (
DisableSCO && !TailCallOpt)
return false;
4802 if (isVarArg)
return false;
4834 if (
Caller.getCallingConv() != CalleeCC &&
4881 PPCTargetLowering::IsEligibleForTailCallOptimization(
SDValue Callee,
4897 for (
unsigned i = 0; i !=
Ins.size(); i++) {
4899 if (Flags.
isByVal())
return false;
4909 return G->getGlobal()->hasHiddenVisibility()
4910 ||
G->getGlobal()->hasProtectedVisibility();
4920 if (!
C)
return nullptr;
4922 int Addr =
C->getZExtValue();
4923 if ((
Addr & 3) != 0 ||
4929 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
4936 struct TailCallArgumentInfo {
4941 TailCallArgumentInfo() =
default;
4951 for (
unsigned i = 0,
e = TailCallArgs.
size(); i !=
e; ++i) {
4953 SDValue FIN = TailCallArgs[i].FrameIdxOp;
4954 int FI = TailCallArgs[i].FrameIdx;
4957 Chain, dl,
Arg, FIN,
4966 int SPDiff,
const SDLoc &dl) {
4972 bool isPPC64 = Subtarget.
isPPC64();
4973 int SlotSize = isPPC64 ? 8 : 4;
4974 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
4976 NewRetAddrLoc,
true);
4979 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
4991 int Offset = ArgOffset + SPDiff;
4992 uint32_t OpSize = (
Arg.getValueSizeInBits() + 7) / 8;
4996 TailCallArgumentInfo
Info;
4998 Info.FrameIdxOp = FIN;
5006 SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5012 LROpOut = getReturnAddrFrameIndex(DAG);
5029 return DAG.
getMemcpy(Chain, dl, Dst, Src, SizeNode,
5038 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5061 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5071 if (!MemOpChains2.
empty())
5091 return G->getGlobal()->getValueType()->isFunctionTy();
5097 SDValue PPCTargetLowering::LowerCallResult(
5105 CCRetInfo.AnalyzeCallResult(
5111 for (
unsigned i = 0,
e = RVLocs.
size(); i !=
e; ++i) {
5120 Chain =
Lo.getValue(1);
5121 InFlag =
Lo.getValue(2);
5125 Chain =
Hi.getValue(1);
5126 InFlag =
Hi.getValue(2);
5192 bool IsStrictFPCall =
false) {
5196 unsigned RetOpc = 0;
5225 if (IsStrictFPCall) {
5256 auto isLocalCallee = [&]() {
5262 !isa_and_nonnull<GlobalIFunc>(GV);
5273 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5287 assert(!isa<GlobalIFunc>(GV) &&
"IFunc is not supported on AIX.");
5288 return getAIXFuncEntryPointSymbolSDNode(GV);
5295 const char *SymName = S->getSymbol();
5302 return getAIXFuncEntryPointSymbolSDNode(
F);
5308 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5316 SymName = getExternalFunctionEntryPointSymbol(SymName)->
getName().
data();
5329 "Expected a CALLSEQ_STARTSDNode.");
5404 const unsigned Alignment = Subtarget.
isPPC64() ? 8 : 4;
5408 Alignment, MMOFlags);
5415 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5422 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5434 "Nest parameter is not supported on AIX.");
5450 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5453 const bool IsPPC64 = Subtarget.
isPPC64();
5502 for (
unsigned i = 0,
e = RegsToPass.size(); i !=
e; ++i)
5504 RegsToPass[i].second.getValueType()));
5519 const uint32_t *
Mask =
5521 assert(
Mask &&
"Missing call preserved mask for calling convention");
5529 SDValue PPCTargetLowering::FinishCall(
5544 if (!CFlags.IsIndirect)
5548 dl, CFlags.HasNest, Subtarget);
5558 if (CFlags.IsTailCall) {
5562 cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
5565 isa<ConstantSDNode>(Callee) ||
5567 "Expecting a global address, external symbol, absolute value, "
5568 "register or an indirect tail call when PC Relative calls are "
5572 "Unexpected call opcode for a tail call.");
5578 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5595 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg,
Ins, dl,
5619 isTailCall = IsEligibleForTailCallOptimization_64SVR4(
5620 Callee, CallConv, CB, isVarArg, Outs,
Ins, DAG);
5622 isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv, isVarArg,
5636 isa<GlobalAddressSDNode>(Callee)) &&
5637 "Callee should be an llvm::Function object.");
5640 <<
"\nTCO callee: ");
5647 "site marked musttail");
5652 if (Subtarget.
useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
5654 Callee = LowerGlobalAddress(Callee, DAG);
5657 CallConv, isTailCall, isVarArg, isPatchPoint,
5665 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals,
Ins, dl, DAG,
5670 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals,
Ins, dl, DAG,
5672 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals,
Ins, dl, DAG,
5676 SDValue PPCTargetLowering::LowerCall_32SVR4(
5687 const bool IsVarArg = CFlags.IsVarArg;
5688 const bool IsTailCall = CFlags.IsTailCall;
5694 const Align PtrAlign(4);
5719 CCInfo.PreAnalyzeCallOperands(Outs);
5725 unsigned NumArgs = Outs.
size();
5727 for (
unsigned i = 0; i != NumArgs; ++i) {
5728 MVT ArgVT = Outs[i].VT;
5732 if (Outs[i].IsFixed) {
5742 errs() <<
"Call operand #" << i <<
" has unhandled type "
5752 CCInfo.clearWasPPCF128();
5759 CCByValInfo.AllocateStack(CCInfo.getNextStackOffset(), PtrAlign);
5766 unsigned NumBytes = CCByValInfo.getNextStackOffset();
5780 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5791 bool seenFloatArg =
false;
5796 for (
unsigned i = 0, RealArgIdx = 0, j = 0,
e = ArgLocs.
size();
5798 ++i, ++RealArgIdx) {
5808 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
5831 Chain = CallSeqStart = NewCallSeqStart;
5857 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
5881 if (!MemOpChains.
empty())
5887 for (
unsigned i = 0,
e = RegsToPass.
size(); i !=
e; ++i) {
5888 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
5889 RegsToPass[i].second, InFlag);
5897 SDValue Ops[] = { Chain, InFlag };
5909 return FinishCall(CFlags, dl, DAG, RegsToPass, InFlag, Chain, CallSeqStart,
5910 Callee, SPDiff, NumBytes,
Ins, InVals, CB);
5915 SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
5927 return NewCallSeqStart;
5930 SDValue PPCTargetLowering::LowerCall_64SVR4(
5939 unsigned NumOps = Outs.
size();
5940 bool IsSibCall =
false;
5944 unsigned PtrByteSize = 8;
5959 assert(!(IsFastCall && CFlags.IsVarArg) &&
5960 "fastcc not supported on varargs functions");
5967 unsigned NumBytes = LinkageSize;
5968 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
5971 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
5972 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
5976 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
5987 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
5988 if (!HasParameterArea) {
5989 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
5990 unsigned AvailableFPRs = NumFPRs;
5991 unsigned AvailableVRs = NumVRs;
5992 unsigned NumBytesTmp = NumBytes;
5993 for (
unsigned i = 0; i != NumOps; ++i) {
5994 if (Outs[i].Flags.
isNest())
continue;
5996 PtrByteSize, LinkageSize, ParamAreaSize,
5997 NumBytesTmp, AvailableFPRs, AvailableVRs))
5998 HasParameterArea =
true;
6004 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6009 HasParameterArea =
false;
6012 for (
unsigned i = 0; i != NumOps; ++i) {
6014 EVT ArgVT = Outs[i].VT;
6015 EVT OrigVT = Outs[i].ArgVT;
6023 if (NumGPRsUsed > NumGPRs)
6024 HasParameterArea =
true;
6031 if (++NumGPRsUsed <= NumGPRs)
6041 if (++NumVRsUsed <= NumVRs)
6045 if (++NumVRsUsed <= NumVRs)
6050 if (++NumFPRsUsed <= NumFPRs)
6054 HasParameterArea =
true;
6061 NumBytes =
alignTo(NumBytes, Alignement);
6065 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6068 unsigned NumBytesActuallyUsed = NumBytes;
6078 if (HasParameterArea)
6079 NumBytes =
std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6081 NumBytes = LinkageSize;
6096 if (CFlags.IsTailCall)
6108 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6119 unsigned ArgOffset = LinkageSize;
6125 for (
unsigned i = 0; i != NumOps; ++i) {
6128 EVT ArgVT = Outs[i].VT;
6129 EVT OrigVT = Outs[i].ArgVT;
6138 auto ComputePtrOff = [&]() {
6142 ArgOffset =
alignTo(ArgOffset, Alignment);
6153 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6154 GPR_idx =
std::min(GPR_idx, NumGPRs);
6186 if (GPR_idx != NumGPRs) {
6192 ArgOffset += PtrByteSize;
6197 if (GPR_idx == NumGPRs &&
Size < 8) {
6199 if (!isLittleEndian) {
6204 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, AddPtr,
6207 ArgOffset += PtrByteSize;
6216 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6217 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, PtrOff,
6222 if (
Size < 8 && GPR_idx != NumGPRs) {
6232 if (!isLittleEndian) {
6236 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, AddPtr,
6247 ArgOffset += PtrByteSize;
6253 for (
unsigned j=0; j<
Size; j+=PtrByteSize) {
6256 if (GPR_idx != NumGPRs) {
6261 ArgOffset += PtrByteSize;
6263 ArgOffset += ((
Size - j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6270 switch (
Arg.getSimpleValueType().SimpleTy) {
6284 if (GPR_idx != NumGPRs) {
6285 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++],
Arg));
6290 assert(HasParameterArea &&
6291 "Parameter area must exist to pass an argument in memory.");
6293 true, CFlags.IsTailCall,
false, MemOpChains,
6294 TailCallArguments, dl);
6296 ArgOffset += PtrByteSize;
6299 ArgOffset += PtrByteSize;
6312 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6313 bool NeededLoad =
false;
6316 if (FPR_idx != NumFPRs)
6320 if (!NeedGPROrStack)
6322 else if (GPR_idx != NumGPRs && !IsFastCall) {
6342 }
else if (ArgOffset % PtrByteSize != 0) {
6346 if (!isLittleEndian)
6354 if (!isLittleEndian)
6364 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6377 assert(HasParameterArea &&
6378 "Parameter area must exist to pass an argument in memory.");
6380 true, CFlags.IsTailCall,
false, MemOpChains,
6381 TailCallArguments, dl);
6388 if (!IsFastCall || NeededLoad) {
6392 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6412 if (CFlags.IsVarArg) {
6413 assert(HasParameterArea &&
6414 "Parameter area must exist if we have a varargs call.");
6420 if (VR_idx != NumVRs) {
6427 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6428 if (GPR_idx == NumGPRs)
6441 if (VR_idx != NumVRs) {
6442 RegsToPass.
push_back(std::make_pair(VR[VR_idx++],
Arg));
6447 assert(HasParameterArea &&
6448 "Parameter area must exist to pass an argument in memory.");
6450 true, CFlags.IsTailCall,
true, MemOpChains,
6451 TailCallArguments, dl);
6462 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6463 "mismatch in size of parameter area");
6464 (void)NumBytesActuallyUsed;
6466 if (!MemOpChains.
empty())
6472 if (CFlags.IsIndirect) {
6476 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6491 if (isELFv2ABI && !CFlags.IsPatchPoint)
6492 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6498 for (
unsigned i = 0,
e = RegsToPass.
size(); i !=
e; ++i) {
6499 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6500 RegsToPass[i].second, InFlag);
6504 if (CFlags.IsTailCall && !IsSibCall)
6508 return FinishCall(CFlags, dl, DAG, RegsToPass, InFlag, Chain, CallSeqStart,
6509 Callee, SPDiff, NumBytes,
Ins, InVals, CB);
6516 "Required alignment greater than stack alignment.");
6536 return RequiredAlign <= 8;
6541 return RequiredAlign <= 4;
6551 const bool IsPPC64 = Subtarget.
isPPC64();
6563 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6565 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6566 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6570 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6571 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6576 "register width are not supported.");
6582 if (ByValSize == 0) {
6589 const unsigned StackSize =
alignTo(ByValSize, PtrAlign);
6611 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6618 LocInfo = ArgFlags.
isSExt() ? CCValAssign::LocInfo::SExt
6619 : CCValAssign::LocInfo::ZExt;
6640 for (
unsigned I = 0;
I < StoreSize;
I += PtrAlign.
value()) {
6641 if (
unsigned Reg = State.
AllocateReg(IsPPC64 ? GPR_64 : GPR_32)) {
6642 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6693 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6699 while (NextRegIndex != GPRs.
size() &&
6704 assert(
Reg &&
"Allocating register unexpectedly failed.");
6717 for (
unsigned I = 0;
I !=
VecSize;
I += PtrSize)
6729 if (NextRegIndex == GPRs.
size()) {
6738 if (GPRs[NextRegIndex] == PPC::R9) {
6743 const unsigned FirstReg = State.
AllocateReg(PPC::R9);
6744 const unsigned SecondReg = State.
AllocateReg(PPC::R10);
6745 assert(FirstReg && SecondReg &&
6746 "Allocating R9 or R10 unexpectedly failed.");
6760 for (
unsigned I = 0;
I !=
VecSize;
I += PtrSize) {
6762 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
6778 "i64 should have been split for 32-bit codegen.");
6786 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
6788 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
6790 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
6798 return &PPC::VRRCRegClass;
6823 "Reg must be a valid argument register!");
6824 return LASize + 4 * (
Reg - PPC::R3);
6829 "Reg must be a valid argument register!");
6830 return LASize + 8 * (
Reg - PPC::X3);
6876 SDValue PPCTargetLowering::LowerFormalArguments_AIX(
6883 "Unexpected calling convention!");
6894 const bool IsPPC64 = Subtarget.
isPPC64();
6895 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
6907 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
6908 CCInfo.AnalyzeFormalArguments(
Ins,
CC_AIX);
6912 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
6926 auto HandleMemLoc = [&]() {
6929 assert((ValSize <= LocSize) &&
6930 "Object size is larger than size of MemLoc");
6933 if (LocSize > ValSize)
6934 CurArgOffset += LocSize - ValSize;
6936 const bool IsImmutable =
6951 assert(isVarArg &&
"Only use custom memloc for vararg.");
6954 const unsigned OriginalValNo = VA.
getValNo();
6955 (void)OriginalValNo;
6957 auto HandleCustomVecRegLoc = [&]() {
6958 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
6959 "Missing custom RegLoc.");
6962 "Unexpected Val type for custom RegLoc.");
6964 "ValNo mismatch between custom MemLoc and RegLoc.");
6975 HandleCustomVecRegLoc();
6976 HandleCustomVecRegLoc();
6980 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
6982 "Only 2 custom RegLocs expected for 64-bit codegen.");
6983 HandleCustomVecRegLoc();
6984 HandleCustomVecRegLoc();
7028 const unsigned Size =
7058 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7060 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7073 CopyFrom.
getValue(1), dl, CopyFrom,
7083 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7086 "RegLocs should be for ByVal argument.");
7093 if (
Offset != StackSize) {
7095 "Expected MemLoc for remaining bytes.");
7096 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7127 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7129 unsigned CallerReservedArea =
7130 std::max(CCInfo.getNextStackOffset(), LinkageSize + MinParameterSaveArea);
7136 CallerReservedArea =
7146 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7148 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7149 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7150 const unsigned NumGPArgRegs =
array_lengthof(IsPPC64 ? GPR_64 : GPR_32);
7155 for (
unsigned GPRIndex =
7156 (CCInfo.getNextStackOffset() - LinkageSize) / PtrByteSize;
7157 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7160 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7161 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7173 if (!MemOps.
empty())
7179 SDValue PPCTargetLowering::LowerCall_AIX(
7192 "Unexpected calling convention!");
7194 if (CFlags.IsPatchPoint)
7202 AIXCCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7210 const bool IsPPC64 = Subtarget.
isPPC64();
7212 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7213 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7214 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7222 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7223 const unsigned NumBytes =
std::max(LinkageSize + MinParameterSaveAreaSize,
7224 CCInfo.getNextStackOffset());
7240 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7241 const unsigned ValNo = ArgLocs[
I].getValNo();
7254 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7263 unsigned LoadOffset = 0;
7266 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7269 LoadOffset += PtrByteSize;
7272 "Unexpected location for pass-by-value argument.");
7276 if (LoadOffset == ByValSize)
7280 assert(ArgLocs[
I].getValNo() == ValNo &&
7281 "Expected additional location for by-value argument.");
7283 if (ArgLocs[
I].isMemLoc()) {
7284 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7289 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7295 CallSeqStart, MemcpyFlags, DAG, dl);
7304 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7305 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7306 "Unexpected register residue for by-value argument.");
7308 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7322 "Unexpected load emitted during handling of pass-by-value "
7330 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7365 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7373 const unsigned OriginalValNo = VA.
getValNo();
7375 unsigned LoadOffset = 0;
7376 auto HandleCustomVecRegLoc = [&]() {
7377 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7378 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7379 "Expected custom RegLoc.");
7382 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7388 LoadOffset += PtrByteSize;
7394 HandleCustomVecRegLoc();
7395 HandleCustomVecRegLoc();
7397 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7398 ArgLocs[
I].getValNo() == OriginalValNo) {
7400 "Only 2 custom RegLocs expected for 64-bit codegen.");
7401 HandleCustomVecRegLoc();
7402 HandleCustomVecRegLoc();
7420 "Unexpected register handling for calling convention.");
7426 "Custom register handling only expected for VarArg.");
7435 else if (
Arg.getValueType().getFixedSizeInBits() <
7444 "Unexpected custom register for argument!");
7465 if (!MemOpChains.
empty())
7470 if (CFlags.IsIndirect) {
7471 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7475 const unsigned TOCSaveOffset =
7491 for (
auto Reg : RegsToPass) {
7496 const int SPDiff = 0;
7497 return FinishCall(CFlags, dl, DAG, RegsToPass, InFlag, Chain, CallSeqStart,
7498 Callee, SPDiff, NumBytes,
Ins, InVals, CB);
7508 return CCInfo.CheckReturn(
7523 CCInfo.AnalyzeReturn(Outs,
7532 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7574 RetOps.push_back(
Flag);
7580 PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7585 EVT IntVT =
Op.getValueType();
7589 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7591 SDValue Ops[2] = {Chain, FPSIdx};
7605 bool isPPC64 = Subtarget.
isPPC64();
7606 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7626 bool isPPC64 = Subtarget.
isPPC64();
7647 PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7649 bool isPPC64 = Subtarget.
isPPC64();
7683 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7684 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
7695 bool isPPC64 = Subtarget.
isPPC64();
7707 Op.getOperand(0),
Op.getOperand(1));
7714 Op.getOperand(0),
Op.getOperand(1));
7718 if (
Op.getValueType().isVector())
7719 return LowerVectorLoad(
Op, DAG);
7722 "Custom lowering only for i1 loads");
7743 if (
Op.getOperand(1).getValueType().isVector())
7744 return LowerVectorStore(
Op, DAG);
7747 "Custom lowering only for i1 stores");
7767 "Custom lowering only for i1 results");
7795 EVT TrgVT =
Op.getValueType();
7807 if (SrcSize > 256 ||
7819 if (SrcSize == 256) {
7830 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
7838 for (
unsigned i = 0; i < TrgNumElts; ++i)
7841 for (
unsigned i = 1; i <= TrgNumElts; ++i)
7845 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
7858 EVT ResVT =
Op.getValueType();
7859 EVT CmpVT =
Op.getOperand(0).getValueType();
7861 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8012 bool IsStrict =
Op->isStrictFPOpcode();
8021 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8023 assert(Src.getValueType().isFloatingPoint());
8024 if (Src.getValueType() ==
MVT::f32) {
8029 Chain = Src.getValue(1);
8035 switch (
Op.getSimpleValueType().SimpleTy) {
8043 "i64 FP_TO_UINT is supported only with FPCVT");
8049 {Chain, Src}, Flags);
8056 void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8058 const SDLoc &dl)
const {
8062 bool IsStrict =
Op->isStrictFPOpcode();
8066 (IsSigned || Subtarget.
hasFPCVT());
8068 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
8077 Alignment =
Align(4);
8080 SDValue Ops[] = { Chain, Tmp, FIPtr };
8084 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8088 if (
Op.getValueType() ==
MVT::i32 && !i32Stack) {
8097 RLI.Alignment = Alignment;
8105 const SDLoc &dl)
const {
8108 if (
Op->isStrictFPOpcode())
8115 const SDLoc &dl)
const {
8116 bool IsStrict =
Op->isStrictFPOpcode();
8119 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8120 EVT SrcVT = Src.getValueType();
8121 EVT DstVT =
Op.getValueType();
8148 {Op.getOperand(0), Lo, Hi}, Flags);
8151 {Res.getValue(1), Res}, Flags);
8157 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8181 {Chain, Src, FltOfs}, Flags);
8185 {Chain, Val}, Flags);
8188 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8207 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8210 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8212 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8213 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8224 bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8229 if (
Op->isStrictFPOpcode())
8238 Op.getOperand(0).getValueType())) {
8240 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8245 if (!
LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8246 LD->isNonTemporal())
8248 if (
LD->getMemoryVT() != MemVT)
8258 RLI.Ptr =
LD->getBasePtr();
8259 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8261 "Non-pre-inc AM on PPC?");
8266 RLI.Chain =
LD->getChain();
8267 RLI.MPI =
LD->getPointerInfo();
8268 RLI.IsDereferenceable =
LD->isDereferenceable();
8269 RLI.IsInvariant =
LD->isInvariant();
8270 RLI.Alignment =
LD->getAlign();
8271 RLI.AAInfo =
LD->getAAInfo();
8272 RLI.Ranges =
LD->getRanges();
8274 RLI.ResChain =
SDValue(
LD,
LD->isIndexed() ? 2 : 1);
8282 void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
8288 SDLoc dl(NewResChain);
8293 "A new TF really is required here");
8302 bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8303 SDNode *Origin =
Op.getOperand(0).getNode();
8318 if (UI.getUse().get().getResNo() != 0)
8348 if (
Op->isStrictFPOpcode()) {
8350 Chain =
Op.getOperand(0);
8354 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8362 const SDLoc &dl)
const {
8365 "Invalid floating point type as target of conversion");
8367 "Int to FP conversions with direct moves require FPCVT");
8368 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8369 bool WordInt = Src.getSimpleValueType().SimpleTy ==
MVT::i32;
8391 for (
unsigned i = 1; i < NumConcat; ++i)
8398 const SDLoc &dl)
const {
8399 bool IsStrict =
Op->isStrictFPOpcode();
8400 unsigned Opc =
Op.getOpcode();
8401 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8404 "Unexpected conversion type");
8406 "Supports conversions to v2f64/v4f32 only.");
8421 for (
unsigned i = 0; i < WideNumElts; ++i)
8424 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8425 int SaveElts = FourEltRes ? 4 : 2;
8427 for (
int i = 0; i < SaveElts; i++)
8428 ShuffV[i * Stride] = i;
8430 for (
int i = 1; i <= SaveElts; i++)
8431 ShuffV[i * Stride - 1] = i - 1;
8439 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8440 EVT ExtVT = Src.getValueType();
8452 {Op.getOperand(0), Extend}, Flags);
8454 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8462 bool IsStrict =
Op->isStrictFPOpcode();
8463 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8470 EVT InVT = Src.getValueType();
8471 EVT OutVT =
Op.getValueType();
8474 return LowerINT_TO_FPVector(
Op, DAG, dl);
8484 if (Src.getValueType() ==
MVT::i1) {
8498 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8501 "UINT_TO_FP is supported only with FPCVT");
8503 if (Src.getValueType() ==
MVT::i64) {
8557 if (canReuseLoadAddress(SINT,
MVT::i64, RLI, DAG)) {
8559 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8560 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8565 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8566 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8570 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8575 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8576 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8580 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8598 "Expected an i32 store");
8604 RLI.Alignment =
Align(4);
8608 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8609 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8614 Chain =
Bits.getValue(1);
8620 Chain =
FP.getValue(1);
8626 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8635 "Unhandled INT_TO_FP type in custom expander!");
8648 if (!(ReusingLoad = canReuseLoadAddress(Src,
MVT::i32, RLI, DAG))) {
8658 "Expected an i32 store");
8664 RLI.Alignment =
Align(4);
8669 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8670 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8676 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
8679 "i32->FP without LFIWAX supported only on PPC64");
8688 Chain, dl, Ext64, FIdx,
8702 Chain =
FP.getValue(1);
8707 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8738 EVT VT =
Op.getValueType();
8744 Chain =
MFFS.getValue(1);
8758 "Stack slot adjustment is valid only on big endian subtargets!");
8788 EVT VT =
Op.getValueType();
8792 VT ==
Op.getOperand(1).getValueType() &&
8812 SDValue OutOps[] = { OutLo, OutHi };
8817 EVT VT =
Op.getValueType();
8821 VT ==
Op.getOperand(1).getValueType() &&
8841 SDValue OutOps[] = { OutLo, OutHi };
8847 EVT VT =
Op.getValueType();
8850 VT ==
Op.getOperand(1).getValueType() &&
8870 SDValue OutOps[] = { OutLo, OutHi };
8877 EVT VT =
Op.getValueType();
8884 EVT AmtVT =
Z.getValueType();
8907 static const MVT VTys[] = {
8914 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
8919 EVT CanonicalVT = VTys[SplatSize-1];
8963 for (
unsigned i = 0; i != 16; ++i)
8991 bool IsSplat =
true;
8992 bool IsLoad =
false;
9019 return !(IsSplat && IsLoad);
9057 APFloat APFloatToConvert = ArgAPFloat;
9058 bool LosesInfo =
true;
9063 ArgAPFloat = APFloatToConvert;
9085 APFloat APFloatToConvert = ArgAPFloat;
9086 bool LosesInfo =
true;
9090 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9095 LoadSDNode *InputNode = dyn_cast<LoadSDNode>(
Op.getOperand(0));
9099 EVT Ty =
Op->getValueType(0);
9138 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9141 APInt APSplatBits, APSplatUndef;
9142 unsigned SplatBitSize;
9144 bool BVNIsConstantSplat =
9152 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9166 (uint32_t)((APSplatBits.
getZExtValue() & 0xFFFFFFFF00000000LL) >> 32);
9191 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9198 const SDValue *InputLoad = &
Op.getOperand(0);
9203 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9204 unsigned ElementSize =
9207 assert(((ElementSize == 2 * MemorySize)
9211 "Unmatched element size and opcode!\n");
9216 unsigned NumUsesOfInputLD = 128 / ElementSize;
9218 if (BVInOp.isUndef())
9233 if (NumUsesOfInputLD == 1 &&
9245 Subtarget.
isISA3_1() && ElementSize <= 16)
9248 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9258 LD->getMemoryVT(),
LD->getMemOperand());
9279 unsigned SplatSize = SplatBitSize / 8;
9284 if (SplatBits == 0) {
9300 Op.getValueType(), DAG, dl);
9312 int32_t SextVal= (int32_t(SplatBits << (32-SplatBitSize)) >>
9314 if (SextVal >= -16 && SextVal <= 15)
9327 if (SextVal >= -32 && SextVal <= 31) {
9336 if (VT ==
Op.getValueType())
9345 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9359 static const signed char SplatCsts[] = {
9360 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9361 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9367 int i = SplatCsts[idx];
9371 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9374 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9376 static const unsigned IIDs[] = {
9377 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9378 Intrinsic::ppc_altivec_vslw
9385 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9387 static const unsigned IIDs[] = {
9388 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9389 Intrinsic::ppc_altivec_vsrw
9396 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9397 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9399 static const unsigned IIDs[] = {
9400 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9401 Intrinsic::ppc_altivec_vrlw
9408 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9414 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9420 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9435 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9436 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9437 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9453 if (LHSID == (1*9+2)*9+3)
return LHS;
9454 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9466 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9467 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9468 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9469 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9472 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9473 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9474 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9475 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9478 for (
unsigned i = 0; i != 16; ++i)
9479 ShufIdxs[i] = (i&3)+0;
9482 for (
unsigned i = 0; i != 16; ++i)
9483 ShufIdxs[i] = (i&3)+4;
9486 for (
unsigned i = 0; i != 16; ++i)
9487 ShufIdxs[i] = (i&3)+8;
9490 for (
unsigned i = 0; i != 16; ++i)
9491 ShufIdxs[i] = (i&3)+12;
9512 const unsigned BytesInVector = 16;
9517 unsigned ShiftElts = 0, InsertAtByte = 0;
9521 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9522 0, 15, 14, 13, 12, 11, 10, 9};
9523 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9524 1, 2, 3, 4, 5, 6, 7, 8};
9527 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9539 bool FoundCandidate =
false;
9543 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
9546 for (
unsigned i = 0; i < BytesInVector; ++i) {
9547 unsigned CurrentElement =
Mask[i];
9550 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
9553 bool OtherElementsInOrder =
true;
9556 for (
unsigned j = 0; j < BytesInVector; ++j) {
9563 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
9564 if (
Mask[j] != OriginalOrder[j] + MaskOffset) {
9565 OtherElementsInOrder =
false;
9572 if (OtherElementsInOrder) {
9579 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
9580 : BigEndianShifts[CurrentElement & 0xF];
9581 Swap = CurrentElement < BytesInVector;
9583 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
9584 FoundCandidate =
true;
9589 if (!FoundCandidate)
9613 const unsigned NumHalfWords = 8;
9614 const unsigned BytesInVector = NumHalfWords * 2;
9623 unsigned ShiftElts = 0, InsertAtByte = 0;
9627 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
9628 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
9631 uint32_t OriginalOrderLow = 0x1234567;
9632 uint32_t OriginalOrderHigh = 0x89ABCDEF;
9635 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9636 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9637 Mask |= ((uint32_t)(
N->getMaskElt(i * 2) / 2) << MaskShift);
9653 bool FoundCandidate =
false;
9656 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9657 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9658 uint32_t MaskOneElt = (
Mask >> MaskShift) & 0xF;
9659 uint32_t MaskOtherElts = ~(0xF << MaskShift);
9660 uint32_t TargetOrder = 0x0;
9667 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
9668 TargetOrder = OriginalOrderLow;
9672 if (MaskOneElt == VINSERTHSrcElem &&
9673 (
Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9674 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9675 FoundCandidate =
true;
9681 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
9683 if ((
Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9685 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
9686 : BigEndianShifts[MaskOneElt & 0x7];
9687 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9688 Swap = MaskOneElt < NumHalfWords;
9689 FoundCandidate =
true;
9695 if (!FoundCandidate)
9730 auto ShuffleMask = SVN->
getMask();
9742 ShuffleMask = cast<ShuffleVectorSDNode>(
VecShuffle)->getMask();
9751 APInt APSplatValue, APSplatUndef;
9752 unsigned SplatBitSize;
9768 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
9769 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
9770 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
9772 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
9773 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
9774 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
9782 for (; SplatBitSize < 32; SplatBitSize <<= 1)
9783 SplatVal |= (SplatVal << SplatBitSize);
9798 "Only set v1i128 as custom, other type shouldn't reach here!");
9803 if (SHLAmt % 8 == 0) {
9805 std::iota(
Mask.begin(),
Mask.end(), 0);
9835 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
9836 if (!isa<ShuffleVectorSDNode>(NewShuffle))
9839 SVOp = cast<ShuffleVectorSDNode>(
Op);
9840 V1 =
Op.getOperand(0);
9841 V2 =
Op.getOperand(1);
9843 EVT VT =
Op.getValueType();
9846 unsigned ShiftElts, InsertAtByte;
9852 bool IsPermutedLoad =
false;
9854 if (InputLoad && Subtarget.
hasVSX() &&
V2.isUndef() &&
9864 if (IsPermutedLoad) {
9865 assert((isLittleEndian || IsFourByte) &&
9866 "Unexpected size for permuted load on big endian target");
9867 SplatIdx += IsFourByte ? 2 : 1;
9868 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
9869 "Splat of a value outside of the loaded memory");
9874 if ((IsFourByte && Subtarget.
hasP9Vector()) || !IsFourByte) {
9877 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
9879 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
9883 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
9899 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
9927 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
9928 return SplatInsertNode;
9933 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
9936 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
9940 if (Subtarget.
hasVSX() &&
9953 if (Subtarget.
hasVSX() &&
9986 if (Subtarget.
hasVSX()) {
10007 if (
V2.isUndef()) {
10031 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10051 unsigned PFIndexes[4];
10052 bool isFourElementShuffle =
true;
10053 for (
unsigned i = 0; i != 4 && isFourElementShuffle; ++i) {
10054 unsigned EltNo = 8;
10055 for (
unsigned j = 0; j != 4; ++j) {
10056 if (PermMask[i*4+j] < 0)
10059 unsigned ByteSource = PermMask[i*4+j];
10060 if ((ByteSource & 3) != j) {
10061 isFourElementShuffle =
false;
10066 EltNo = ByteSource/4;
10067 }
else if (EltNo != ByteSource/4) {
10068 isFourElementShuffle =
false;
10072 PFIndexes[i] = EltNo;
10080 if (isFourElementShuffle && !isLittleEndian) {
10082 unsigned PFTableIndex =
10083 PFIndexes[0]*9*9*9+PFIndexes[1]*9*9+PFIndexes[2]*9+PFIndexes[3];
10086 unsigned Cost = (PFEntry >> 30);
10105 if (
V2.isUndef())
V2 = V1;
10119 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10121 for (
unsigned j = 0; j != BytesPerElement; ++j)
10122 if (isLittleEndian)
10130 ShufflesHandledWithVPERM++;
10132 LLVM_DEBUG(
dbgs() <<
"Emitting a VPERM for the following shuffle:\n");
10134 LLVM_DEBUG(
dbgs() <<
"With the following permute control vector:\n");
10137 if (isLittleEndian)
10139 V2, V1, VPermMask);
10142 V1,
V2, VPermMask);
10150 unsigned IntrinsicID =
10151 cast<ConstantSDNode>(Intrin.
getOperand(0))->getZExtValue();
10154 switch (IntrinsicID) {
10158 case Intrinsic::ppc_altivec_vcmpbfp_p:
10162 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10166 case Intrinsic::ppc_altivec_vcmpequb_p:
10170 case Intrinsic::ppc_altivec_vcmpequh_p:
10174 case Intrinsic::ppc_altivec_vcmpequw_p:
10178 case Intrinsic::ppc_altivec_vcmpequd_p:
10185 case Intrinsic::ppc_altivec_vcmpneb_p:
10186 case Intrinsic::ppc_altivec_vcmpneh_p:
10187 case Intrinsic::ppc_altivec_vcmpnew_p:
10188 case Intrinsic::ppc_altivec_vcmpnezb_p:
10189 case Intrinsic::ppc_altivec_vcmpnezh_p:
10190 case Intrinsic::ppc_altivec_vcmpnezw_p:
10192 switch (IntrinsicID) {
10195 case Intrinsic::ppc_altivec_vcmpneb_p:
10198 case Intrinsic::ppc_altivec_vcmpneh_p:
10201 case Intrinsic::ppc_altivec_vcmpnew_p:
10204 case Intrinsic::ppc_altivec_vcmpnezb_p:
10207 case Intrinsic::ppc_altivec_vcmpnezh_p:
10210 case Intrinsic::ppc_altivec_vcmpnezw_p:
10218 case Intrinsic::ppc_altivec_vcmpgefp_p:
10222 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10226 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10230 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10234 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10238 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10245 case Intrinsic::ppc_altivec_vcmpgtub_p:
10249 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10253 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10257 case Intrinsic::ppc_altivec_vcmpgtud_p:
10265 case Intrinsic::ppc_altivec_vcmpequq:
10266 case Intrinsic::ppc_altivec_vcmpgtsq:
10267 case Intrinsic::ppc_altivec_vcmpgtuq:
10270 switch (IntrinsicID) {
10273 case Intrinsic::ppc_altivec_vcmpequq:
10276 case Intrinsic::ppc_altivec_vcmpgtsq:
10279 case Intrinsic::ppc_altivec_vcmpgtuq:
10286 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10287 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10288 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10289 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10290 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10291 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10292 if (Subtarget.
hasVSX()) {
10293 switch (IntrinsicID) {
10294 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10297 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10300 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10303 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10306 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10309 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10319 case Intrinsic::ppc_altivec_vcmpbfp:
10322 case Intrinsic::ppc_altivec_vcmpeqfp:
10325 case Intrinsic::ppc_altivec_vcmpequb:
10328 case Intrinsic::ppc_altivec_vcmpequh:
10331 case Intrinsic::ppc_altivec_vcmpequw:
10334 case Intrinsic::ppc_altivec_vcmpequd:
10340 case Intrinsic::ppc_altivec_vcmpneb:
10341 case Intrinsic::ppc_altivec_vcmpneh:
10342 case Intrinsic::ppc_altivec_vcmpnew:
10343 case Intrinsic::ppc_altivec_vcmpnezb:
10344 case Intrinsic::ppc_altivec_vcmpnezh:
10345 case Intrinsic::ppc_altivec_vcmpnezw:
10347 switch (IntrinsicID) {
10350 case Intrinsic::ppc_altivec_vcmpneb:
10353 case Intrinsic::ppc_altivec_vcmpneh:
10356 case Intrinsic::ppc_altivec_vcmpnew:
10359 case Intrinsic::ppc_altivec_vcmpnezb:
10362 case Intrinsic::ppc_altivec_vcmpnezh:
10365 case Intrinsic::ppc_altivec_vcmpnezw:
10372 case Intrinsic::ppc_altivec_vcmpgefp:
10375 case Intrinsic::ppc_altivec_vcmpgtfp:
10378 case Intrinsic::ppc_altivec_vcmpgtsb:
10381 case Intrinsic::ppc_altivec_vcmpgtsh:
10384 case Intrinsic::ppc_altivec_vcmpgtsw:
10387 case Intrinsic::ppc_altivec_vcmpgtsd:
10393 case Intrinsic::ppc_altivec_vcmpgtub:
10396 case Intrinsic::ppc_altivec_vcmpgtuh:
10399 case Intrinsic::ppc_altivec_vcmpgtuw:
10402 case Intrinsic::ppc_altivec_vcmpgtud:
10408 case Intrinsic::ppc_altivec_vcmpequq_p:
10409 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10410 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10413 switch (IntrinsicID) {
10416 case Intrinsic::ppc_altivec_vcmpequq_p:
10419 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10422 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10436 unsigned IntrinsicID =
10437 cast<ConstantSDNode>(
Op.getOperand(0))->getZExtValue();
10441 switch (IntrinsicID) {
10442 case Intrinsic::thread_pointer:
10448 case Intrinsic::ppc_mma_disassemble_acc:
10449 case Intrinsic::ppc_vsx_disassemble_pair: {
10452 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
10457 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
10468 case Intrinsic::ppc_unpack_longdouble: {
10469 auto *Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
10470 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
10471 "Argument of long double unpack must be 0 or 1!");
10474 Idx->getValueType(0)));
10477 case Intrinsic::ppc_compare_exp_lt:
10478 case Intrinsic::ppc_compare_exp_gt:
10479 case Intrinsic::ppc_compare_exp_eq:
10480 case Intrinsic::ppc_compare_exp_uo: {
10482 switch (IntrinsicID) {
10483 case Intrinsic::ppc_compare_exp_lt:
10486 case Intrinsic::ppc_compare_exp_gt:
10489 case Intrinsic::ppc_compare_exp_eq:
10492 case Intrinsic::ppc_compare_exp_uo:
10499 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
10500 Op.getOperand(1), Op.getOperand(2)),
10502 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
10503 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
10506 case Intrinsic::ppc_test_data_class_d:
10507 case Intrinsic::ppc_test_data_class_f: {
10508 unsigned CmprOpc = PPC::XSTSTDCDP;
10509 if (IntrinsicID == Intrinsic::ppc_test_data_class_f)
10510 CmprOpc = PPC::XSTSTDCSP;
10514 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
10517 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
10518 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
10521 case Intrinsic::ppc_convert_f128_to_ppcf128:
10522 case Intrinsic::ppc_convert_ppcf128_to_f128: {
10523 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
10524 ? RTLIB::CONVERT_PPCF128_F128
10525 : RTLIB::CONVERT_F128_PPCF128;
10526 MakeLibCallOptions CallOptions;
10527 std::pair<SDValue, SDValue>
Result =
10528 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
10544 Op.getOperand(1),
Op.getOperand(2),
10567 switch (cast<ConstantSDNode>(
Op.getOperand(1))->getZExtValue()) {
10570 BitNo = 0; InvertBit =
false;
10573 BitNo = 0; InvertBit =
true;
10576 BitNo = 2; InvertBit =
false;
10579 BitNo = 2; InvertBit =
true;
10601 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
10603 switch (cast<ConstantSDNode>(
Op.getOperand(ArgStart))->getZExtValue()) {
10604 case Intrinsic::ppc_cfence: {
10605 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
10606 assert(Subtarget.
isPPC64() &&
"Only 64-bit is supported for now.");
10607 SDValue Val =
Op.getOperand(ArgStart + 1);
10637 int VectorIndex = 0;
10650 "Expecting an atomic compare-and-swap here.");
10652 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
10653 EVT MemVT = AtomicNode->getMemoryVT();
10671 for (
int i = 0,
e = AtomicNode->getNumOperands(); i <
e; i++)
10672 Ops.
push_back(AtomicNode->getOperand(i));
10684 EVT MemVT =
N->getMemoryVT();
10686 "Expect quadword atomic operations");
10688 unsigned Opc =
N->getOpcode();
10697 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
10700 Ops, MemVT,
N->getMemOperand());
10727 N->getMemOperand());
10753 "Should only be called for ISD::INSERT_VECTOR_ELT");
10757 EVT VT =
Op.getValueType();
10775 (isa<LoadSDNode>(
V2))) {
10780 BitcastLoad,
Op.getOperand(2));
10804 unsigned InsertAtElement =
C->getZExtValue();
10805 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
10807 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
10821 EVT VT =
Op.getValueType();
10830 "Type unsupported without MMA");
10832 "Type unsupported without paired vector support");
10837 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
10867 EVT StoreVT =
Value.getValueType();
10876 "Type unsupported without MMA");
10878 "Type unsupported without paired vector support");
10881 unsigned NumVecs = 2;
10886 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
10887 unsigned VecNum = Subtarget.
isLittleEndian() ? NumVecs - 1 - Idx : Idx;
10891 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
10949 for (
unsigned i = 0; i != 8; ++i) {
10950 if (isLittleEndian) {
10952 Ops[i*2+1] = 2*i+16;
10955 Ops[i*2+1] = 2*i+1+16;
10958 if (isLittleEndian)
10968 bool IsStrict =
Op->isStrictFPOpcode();
10969 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() ==
MVT::f128 &&
10980 "Should only be called for ISD::FP_EXTEND");
10997 "Node should have 2 operands with second one being a constant!");
11003 int Idx = cast<ConstantSDNode>(Op0.
getOperand(1))->getZExtValue();
11009 int DWord = Idx >> 1;
11029 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
11032 LD->getMemoryVT(),
LD->getMemOperand());
11042 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
11045 LD->getMemoryVT(),
LD->getMemOperand());
11056 switch (
Op.getOpcode()) {
11079 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
11105 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
11106 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
11118 return LowerFP_ROUND(
Op, DAG);
11131 return LowerINTRINSIC_VOID(
Op, DAG);
11133 return LowerBSWAP(
Op, DAG);
11135 return LowerATOMIC_CMP_SWAP(
Op, DAG);
11137 return LowerATOMIC_LOAD_STORE(
Op, DAG);
11145 switch (
N->getOpcode()) {
11147 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
11164 if (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue() !=
11165 Intrinsic::loop_decrement)
11169 "Unexpected result type for CTR decrement intrinsic");
11171 N->getValueType(0));
11181 switch (cast<ConstantSDNode>(
N->getOperand(0))->getZExtValue()) {
11182 case Intrinsic::ppc_pack_longdouble:
11184 N->getOperand(2),
N->getOperand(1)));
11186 case Intrinsic::ppc_convert_f128_to_ppcf128:
11196 EVT VT =
N->getValueType(0);
11211 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
11215 Results.push_back(LoweredValue);
11216 if (
N->isStrictFPOpcode())
11221 if (!
N->getValueType(0).isVector())
11248 Module *M =
Builder.GetInsertBlock()->getParent()->getParent();
11250 return Builder.CreateCall(Func, {});
11272 if (isa<LoadInst>(Inst) && Subtarget.
isPPC64())
11275 Builder.GetInsertBlock()->getParent()->getParent(),
11276 Intrinsic::ppc_cfence, {Inst->getType()}),
11286 unsigned AtomicSize,
11287 unsigned BinOpcode,
11288 unsigned CmpOpcode,
11289 unsigned CmpPred)
const {
11293 auto LoadMnemonic = PPC::LDARX;
11294 auto StoreMnemonic = PPC::STDCX;
11295 switch (AtomicSize) {
11299 LoadMnemonic = PPC::LBARX;
11300 StoreMnemonic = PPC::STBCX;
11304 LoadMnemonic = PPC::LHARX;
11305 StoreMnemonic = PPC::STHCX;
11309 LoadMnemonic = PPC::LWARX;
11310 StoreMnemonic = PPC::STWCX;
11313 LoadMnemonic = PPC::LDARX;
11314 StoreMnemonic = PPC::STDCX;
11330 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
11332 F->insert(It, loopMBB);
11334 F->insert(It, loop2MBB);
11335 F->insert(It, exitMBB);
11341 Register TmpReg = (!BinOpcode) ? incr :
11343 : &PPC::GPRCRegClass);
11348 BB->addSuccessor(loopMBB);
11374 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
11376 BuildMI(
BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
11386 BB->addSuccessor(loop2MBB);
11387 BB->addSuccessor(exitMBB);
11394 BB->addSuccessor(loopMBB);
11395 BB->addSuccessor(exitMBB);
11404 switch(
MI.getOpcode()) {
11408 return TII->isSignExtended(
MI);
11432 case PPC::EXTSB8_32_64:
11433 case PPC::EXTSB8_rec:
11434 case PPC::EXTSB_rec:
11437 case PPC::EXTSH8_32_64:
11438 case PPC::EXTSH8_rec:
11439 case PPC::EXTSH_rec:
11442 case PPC::EXTSWSLI_32_64:
11443 case PPC::EXTSWSLI_32_64_rec:
11444 case PPC::EXTSWSLI_rec:
11445 case PPC::EXTSW_32:
11446 case PPC::EXTSW_32_64:
11447 case PPC::EXTSW_32_64_rec:
11448 case PPC::EXTSW_rec:
11451 case PPC::SRAWI_rec:
11452 case PPC::SRAW_rec:
11461 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
11474 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
11476 BuildMI(*
BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
11477 .
addReg(
MI.getOperand(3).getReg());
11478 MI.getOperand(3).setReg(ValueReg);
11489 bool is64bit = Subtarget.
isPPC64();
11491 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
11502 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
11504 F->insert(It, loopMBB);
11506 F->insert(It, loop2MBB);
11507 F->insert(It, exitMBB);
11513 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
11536 BB->addSuccessor(loopMBB);
11558 if (ptrA != ZeroReg) {
11560 BuildMI(
BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
11569 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
11572 .
addImm(is8bit ? 28 : 27);
11573 if (!isLittleEndian)
11576 .
addImm(is8bit ? 24 : 16);
11620 unsigned ValueReg = SReg;
11621 unsigned CmpReg = Incr2Reg;
11622 if (CmpOpcode == PPC::CMPW) {
11628 BuildMI(
BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
11630 ValueReg = ValueSReg;
11640 BB->addSuccessor(loop2MBB);
11641 BB->addSuccessor(exitMBB);
11653 BB->addSuccessor(loopMBB);
11654 BB->addSuccessor(exitMBB);
11664 .
addImm(is8bit ? 24 : 16)
11685 Register DstReg =
MI.getOperand(0).getReg();
11688 Register mainDstReg =
MRI.createVirtualRegister(RC);
11689 Register restoreDstReg =
MRI.createVirtualRegister(RC);
11693 "Invalid Pointer Size!");
11741 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
11742 Register BufReg =
MI.getOperand(1).getReg();
11757 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
11759 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
11762 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
11785 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
11806 TII->get(PPC::PHI), DstReg)
11810 MI.eraseFromParent();
11825 "Invalid Pointer Size!");
11828 (PVT ==
MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
11831 unsigned FP = (PVT ==
MVT::i64) ? PPC::X31 : PPC::R31;
11832 unsigned SP = (PVT ==
MVT::i64) ? PPC::X1 : PPC::R1;
11846 Register BufReg =
MI.getOperand(0).getReg();
11912 MI.eraseFromParent();
11928 "Unexpected stack alignment");
11931 unsigned StackProbeSize = 4096;
11939 return StackProbeSize ? StackProbeSize :
StackAlign;
11951 const bool isPPC64 = Subtarget.
isPPC64();
11983 MF->
insert(MBBIter, TestMBB);
11984 MF->
insert(MBBIter, BlockMBB);
11985 MF->
insert(MBBIter, TailMBB);
11990 Register DstReg =
MI.getOperand(0).getReg();
11991 Register NegSizeReg =
MI.getOperand(1).getReg();
11992 Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
11993 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
11994 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
11995 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12001 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
12003 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
12009 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
12010 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
12012 .
addDef(ActualNegSizeReg)
12014 .
add(
MI.getOperand(2))
12015 .
add(
MI.getOperand(3));
12021 .
addReg(ActualNegSizeReg);
12024 int64_t NegProbeSize = -(int64_t)ProbeSize;
12026 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12028 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12030 .
addImm(NegProbeSize >> 16);
12034 .
addImm(NegProbeSize & 0xFFFF);
12041 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12043 .
addReg(ActualNegSizeReg)
12045 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12049 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12052 .
addReg(ActualNegSizeReg);
12061 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
12062 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
12076 BuildMI(BlockMBB,
DL,
TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
12087 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12090 MaxCallFrameSizeReg)
12091 .
add(
MI.getOperand(2))
12092 .
add(
MI.getOperand(3));
12093 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
12095 .
addReg(MaxCallFrameSizeReg);
12104 MI.eraseFromParent();
12106 ++NumDynamicAllocaProbed;
12113 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
12114 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
12116 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
12129 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
12130 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
12132 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
12133 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
12147 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12148 MI.getOpcode() == PPC::SELECT_CC_I8 ||
MI.getOpcode() == PPC::SELECT_I4 ||
12149 MI.getOpcode() == PPC::SELECT_I8) {
12151 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12152 MI.getOpcode() == PPC::SELECT_CC_I8)
12153 Cond.push_back(
MI.getOperand(4));
12156 Cond.push_back(
MI.getOperand(1));
12159 TII->insertSelect(*
BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
12160 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
12161 }
else if (
MI.getOpcode() == PPC::SELECT_CC_F4 ||
12162 MI.getOpcode() == PPC::SELECT_CC_F8 ||
12163 MI.getOpcode() == PPC::SELECT_CC_F16 ||
12164 MI.getOpcode() == PPC::SELECT_CC_VRRC ||
12165 MI.getOpcode() == PPC::SELECT_CC_VSFRC ||
12166 MI.getOpcode() == PPC::SELECT_CC_VSSRC ||
12167 MI.getOpcode() == PPC::SELECT_CC_VSRC ||
12168 MI.getOpcode() == PPC::SELECT_CC_SPE4 ||
12169 MI.getOpcode() == PPC::SELECT_CC_SPE ||
12170 MI.getOpcode() == PPC::SELECT_F4 ||
12171 MI.getOpcode() == PPC::SELECT_F8 ||
12172 MI.getOpcode() == PPC::SELECT_F16 ||
12173 MI.getOpcode() == PPC::SELECT_SPE ||
12174 MI.getOpcode() == PPC::SELECT_SPE4 ||
12175 MI.getOpcode() == PPC::SELECT_VRRC ||
12176 MI.getOpcode() == PPC::SELECT_VSFRC ||
12177 MI.getOpcode() == PPC::SELECT_VSSRC ||
12178 MI.getOpcode() == PPC::SELECT_VSRC) {
12193 F->insert(It, copy0MBB);
12194 F->insert(It, sinkMBB);
12202 BB->addSuccessor(copy0MBB);
12203 BB->addSuccessor(sinkMBB);
12205 if (
MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8 ||
12206 MI.getOpcode() == PPC::SELECT_F4 ||
MI.getOpcode() == PPC::SELECT_F8 ||
12207 MI.getOpcode() == PPC::SELECT_F16 ||
12208 MI.getOpcode() == PPC::SELECT_SPE4 ||
12209 MI.getOpcode() == PPC::SELECT_SPE ||
12210 MI.getOpcode() == PPC::SELECT_VRRC ||
12211 MI.getOpcode() == PPC::SELECT_VSFRC ||
12212 MI.getOpcode() == PPC::SELECT_VSSRC ||
12213 MI.getOpcode() == PPC::SELECT_VSRC) {
12215 .
addReg(
MI.getOperand(1).getReg())
12218 unsigned SelectPred =
MI.getOperand(4).getImm();
12221 .
addReg(
MI.getOperand(1).getReg())
12231 BB->addSuccessor(sinkMBB);
12237 BuildMI(*
BB,
BB->begin(), dl,
TII->get(PPC::PHI),
MI.getOperand(0).getReg())
12238 .
addReg(
MI.getOperand(3).getReg())
12240 .
addReg(
MI.getOperand(2).getReg())
12242 }
else if (
MI.getOpcode() == PPC::ReadTB) {
12258 F->insert(It, readMBB);
12259 F->insert(It, sinkMBB);
12266 BB->addSuccessor(readMBB);
12288 BB->addSuccessor(readMBB);
12289 BB->addSuccessor(sinkMBB);
12290 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
12292 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
12294 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
12296 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
12299 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
12301 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
12303 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
12305 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
12308 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
12310 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
12312 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
12314 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
12317 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
12319 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
12321 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
12323 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
12326 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
12328 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
12330 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
12332 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
12335 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
12337 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
12339 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
12341 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
12344 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
12346 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
12348 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
12350 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
12353 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
12355 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
12357 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
12359 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
12362 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
12364 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
12366 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
12368 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
12371 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
12373 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
12375 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
12377 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
12380 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
12382 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
12384 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
12386 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
12388 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
12389 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
12391 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
12393 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
12394 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
12396 auto LoadMnemonic = PPC::LDARX;
12397 auto StoreMnemonic = PPC::STDCX;
12398 switch (
MI.getOpcode()) {
12401 case PPC::ATOMIC_CMP_SWAP_I8:
12402 LoadMnemonic = PPC::LBARX;
12403 StoreMnemonic = PPC::STBCX;
12406 case PPC::ATOMIC_CMP_SWAP_I16:
12407 LoadMnemonic = PPC::LHARX;
12408 StoreMnemonic = PPC::STHCX;
12411 case PPC::ATOMIC_CMP_SWAP_I32:
12412 LoadMnemonic = PPC::LWARX;
12413 StoreMnemonic = PPC::STWCX;
12415 case PPC::ATOMIC_CMP_SWAP_I64:
12416 LoadMnemonic = PPC::LDARX;
12417 StoreMnemonic = PPC::STDCX;
12423 Register oldval =
MI.getOperand(3).getReg();
12424 Register newval =
MI.getOperand(4).getReg();
12431 F->insert(It, loop1MBB);
12432 F->insert(It, loop2MBB);
12433 F->insert(It, midMBB);
12434 F->insert(It, exitMBB);
12442 BB->addSuccessor(loop1MBB);
12457 BuildMI(
BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), PPC::CR0)
12464 BB->addSuccessor(loop2MBB);
12465 BB->addSuccessor(midMBB);
12477 BB->addSuccessor(loop1MBB);
12478 BB->addSuccessor(exitMBB);
12485 BB->addSuccessor(exitMBB);
12490 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
12491 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
12495 bool is64bit = Subtarget.
isPPC64();
12497 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
12502 Register oldval =
MI.getOperand(3).getReg();
12503 Register newval =
MI.getOperand(4).getReg();
12510 F->insert(It, loop1MBB);
12511 F->insert(It, loop2MBB);
12512 F->insert(It, midMBB);
12513 F->insert(It, exitMBB);
12520 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12539 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12543 BB->addSuccessor(loop1MBB);
12572 if (ptrA != ZeroReg) {
12574 BuildMI(
BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12584 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12587 .
addImm(is8bit ? 28 : 27);
12588 if (!isLittleEndian)
12591 .
addImm(is8bit ? 24 : 16);
12641 BB->addSuccessor(loop2MBB);
12642 BB->addSuccessor(midMBB);
12660 BB->addSuccessor(loop1MBB);
12661 BB->addSuccessor(exitMBB);
12668 BB->addSuccessor(exitMBB);
12676 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
12711 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
12712 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
12713 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
12714 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
12718 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
12722 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
12726 .
addReg(
MI.getOperand(1).getReg())
12729 MI.getOperand(0).getReg())
12730 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
12731 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
12737 MI.getOperand(0).getReg())
12739 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
12741 unsigned Imm =
MI.getOperand(1).getImm();
12744 MI.getOperand(0).getReg())
12746 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
12748 Register OldFPSCRReg =
MI.getOperand(0).getReg();
12751 if (
MRI.use_empty(OldFPSCRReg))
12752 BuildMI(*
BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
12765 unsigned Mode =
MI.getOperand(1).getImm();
12773 }
else if (
MI.getOpcode() == PPC::SETRND) {
12781 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
12787 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
12790 if (RC == &PPC::F8RCRegClass) {
12793 "Unsupported RegClass.");
12795 StoreOp = PPC::STFD;
12800 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
12801 "Unsupported RegClass.");
12834 Register OldFPSCRReg =
MI.getOperand(0).getReg();
12851 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
12859 BuildMI(*
BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
12873 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
12882 }
else if (
MI.getOpcode() == PPC::SETFLM) {
12886 Register OldFPSCRReg =
MI.getOperand(0).getReg();
12887 if (
MRI.use_empty(OldFPSCRReg))
12888 BuildMI(*
BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
12893 Register NewFPSCRReg =
MI.getOperand(1).getReg();
12899 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
12900 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
12902 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
12909 .
addUse(Src, 0, PPC::sub_gp8_x1);
12912 .
addUse(Src, 0, PPC::sub_gp8_x0);
12913 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
12914 MI.getOpcode() == PPC::STQX_PSEUDO) {
12920 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
12926 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
12927 :
TII->get(PPC::STQ))
12935 MI.eraseFromParent();
12948 int RefinementSteps = Subtarget.
hasRecipPrec() ? 1 : 3;
12951 return RefinementSteps;
12957 EVT VT =
Op.getValueType();
12984 PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
12987 EVT VT =
Op.getValueType();
12996 int Enabled,
int &RefinementSteps,
12997 bool &UseOneConstNR,
12998 bool Reciprocal)
const {
13004 if (RefinementSteps == ReciprocalEstimate::Unspecified)
13017 int &RefinementSteps)
const {
13023 if (RefinementSteps == ReciprocalEstimate::Unspecified)
13030 unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
13068 unsigned Bytes,
int Dist,
13078 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
13079 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
13082 if (
FS != BFS ||
FS != (
int)Bytes)
return false;
13086 SDValue Base1 = Loc, Base2 = BaseLoc;
13087 int64_t Offset1 = 0, Offset2 = 0;
13090 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
13100 if (isGA1 && isGA2 && GV1 == GV2)
13101 return Offset1 == (Offset2 + Dist*Bytes);
13108 unsigned Bytes,
int Dist,
13111 EVT VT =
LS->getMemoryVT();
13118 switch (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue()) {
13119 default:
return false;
13120 case Intrinsic::ppc_altivec_lvx:
13121 case Intrinsic::ppc_altivec_lvxl:
13122 case Intrinsic::ppc_vsx_lxvw4x:
13123 case Intrinsic::ppc_vsx_lxvw4x_be:
13126 case Intrinsic::ppc_vsx_lxvd2x:
13127 case Intrinsic::ppc_vsx_lxvd2x_be:
13130 case Intrinsic::ppc_altivec_lvebx:
13133 case Intrinsic::ppc_altivec_lvehx:
13136 case Intrinsic::ppc_altivec_lvewx:
13146 switch (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue()) {
13147 default:
return false;
13148 case Intrinsic::ppc_altivec_stvx:
13149 case Intrinsic::ppc_altivec_stvxl:
13150 case Intrinsic::ppc_vsx_stxvw4x:
13153 case Intrinsic::ppc_vsx_stxvd2x:
13156 case Intrinsic::ppc_vsx_stxvw4x_be:
13159 case Intrinsic::ppc_vsx_stxvd2x_be:
13162 case Intrinsic::ppc_altivec_stvebx:
13165 case Intrinsic::ppc_altivec_stvehx:
13168 case Intrinsic::ppc_altivec_stvewx:
13186 EVT VT =
LD->getMemoryVT();
13195 while (!Queue.empty()) {
13196 SDNode *ChainNext = Queue.pop_back_val();
13197 if (!Visited.
insert(ChainNext).second)
13200 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
13204 if (!Visited.
count(ChainLD->getChain().getNode()))
13205 Queue.push_back(ChainLD->getChain().getNode());
13207 for (
const SDUse &
O : ChainNext->
ops())
13208 if (!Visited.
count(
O.getNode()))
13209 Queue.push_back(
O.getNode());
13211 LoadRoots.
insert(ChainNext);
13224 Queue.push_back(*
I);
13226 while (!Queue.empty()) {
13227 SDNode *LoadRoot = Queue.pop_back_val();
13228 if (!Visited.
insert(LoadRoot).second)
13231 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
13236 if (((isa<MemSDNode>(U) &&
13237 cast<MemSDNode>(U)->getChain().getNode() == LoadRoot) ||
13240 Queue.push_back(U);
13273 auto Final = Shifted;
13284 DAGCombinerInfo &DCI)
const {
13292 if (!DCI.isAfterLegalizeDAG())
13297 for (
const SDNode *U :
N->uses())
13301 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(2))->get();
13302 auto OpSize =
N->getOperand(0).getValueSizeInBits();
13306 if (OpSize <
Size) {
13324 DAGCombinerInfo &DCI)
const {
13342 if (
N->getOperand(0).getValueType() !=
MVT::i32 &&
13343 N->getOperand(0).getValueType() !=
MVT::i64)
13351 cast<CondCodeSDNode>(
N->getOperand(
13353 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
13364 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
13387 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
13388 N->getOperand(0).getOpcode() !=
ISD::OR &&
13389 N->getOperand(0).getOpcode() !=
ISD::XOR &&
13399 N->getOperand(1).getOpcode() !=
ISD::AND &&
13400 N->getOperand(1).getOpcode() !=
ISD::OR &&
13401 N->getOperand(1).getOpcode() !=
ISD::XOR &&
13414 for (
unsigned i = 0; i < 2; ++i) {
13418 N->getOperand(i).getOperand(0).getValueType() ==
MVT::i1) ||
13419 isa<ConstantSDNode>(
N->getOperand(i)))
13430 while (!BinOps.
empty()) {
13438 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
13472 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
13473 if (isa<ConstantSDNode>(Inputs[i]))
13476 for (
const SDNode *
User : Inputs[i].getNode()->uses()) {
13496 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
13497 for (
const SDNode *
User : PromOps[i].getNode()->uses()) {
13518 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
13521 if (isa<ConstantSDNode>(Inputs[i]))
13527 std::list<HandleSDNode> PromOpHandles;
13528 for (
auto &PromOp : PromOps)
13529 PromOpHandles.emplace_back(PromOp);
13536 while (!PromOpHandles.empty()) {
13538 PromOpHandles.pop_back();
13544 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
13547 PromOpHandles.emplace_front(PromOp);
13552 if (isa<ConstantSDNode>(RepValue))
13561 default:
C = 0;
break;
13566 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
13574 PromOpHandles.emplace_front(PromOp);
13582 for (
unsigned i = 0; i < 2; ++i)
13583 if (isa<ConstantSDNode>(Ops[
C+i]))
13592 return N->getOperand(0);
13600 DAGCombinerInfo &DCI)
const {
13626 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
13627 N->getOperand(0).getOpcode() !=
ISD::OR &&
13628 N->getOperand(0).getOpcode() !=
ISD::XOR &&
13639 while (!BinOps.
empty()) {
13647 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
13678 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
13679 if (isa<ConstantSDNode>(Inputs[i]))
13682 for (
SDNode *
User : Inputs[i].getNode()->uses()) {
13690 SelectTruncOp[0].
insert(std::make_pair(
User,
13694 SelectTruncOp[0].
insert(std::make_pair(
User,
13697 SelectTruncOp[1].
insert(std::make_pair(
User,
13703 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
13704 for (
SDNode *
User : PromOps[i].getNode()->uses()) {
13712 SelectTruncOp[0].
insert(std::make_pair(
User,
13716 SelectTruncOp[0].
insert(std::make_pair(
User,
13719 SelectTruncOp[1].
insert(std::make_pair(
User,
13725 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
13726 bool ReallyNeedsExt =
false;
13730 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
13731 if (isa<ConstantSDNode>(Inputs[i]))
13735 Inputs[i].getOperand(0).getValueSizeInBits();
13736 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
13741 OpBits-PromBits))) ||
13744 (OpBits-(PromBits-1)))) {
13745 ReallyNeedsExt =
true;
13753 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
13757 if (isa<ConstantSDNode>(Inputs[i]))
13760 SDValue InSrc = Inputs[i].getOperand(0);
13774 std::list<HandleSDNode> PromOpHandles;
13775 for (
auto &PromOp : PromOps)
13776 PromOpHandles.emplace_back(PromOp);
13782 while (!PromOpHandles.empty()) {
13784 PromOpHandles.pop_back();
13788 default:
C = 0;
break;
13793 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
13801 PromOpHandles.emplace_front(PromOp);
13811 (SelectTruncOp[1].count(PromOp.
getNode()) &&
13813 PromOpHandles.emplace_front(PromOp);
13822 for (
unsigned i = 0; i < 2; ++i) {
13823 if (!isa<ConstantSDNode>(Ops[
C+i]))
13840 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
13841 if (SI0 != SelectTruncOp[0].
end())
13843 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
13844 if (SI1 != SelectTruncOp[1].
end())
13853 if (!ReallyNeedsExt)
13854 return N->getOperand(0);
13861 N->getValueSizeInBits(0), PromBits),
13862 dl,
N->getValueType(0)));
13865 "Invalid extension type");
13868 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
13876 DAGCombinerInfo &DCI)
const {
13878 "Should be called with a SETCC node");
13880 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(2))->get();
13896 EVT VT =
N->getValueType(0);
13897 EVT OpVT =
LHS.getValueType();
13903 return DAGCombineTruncBoolExt(
N, DCI);
13922 combineElementTruncationToVectorTruncation(
SDNode *
N,
13923 DAGCombinerInfo &DCI)
const {
13925 "Should be called with a BUILD_VECTOR node");
13930 SDValue FirstInput =
N->getOperand(0);
13932 "The input operand must be an fp-to-int conversion.");
13941 bool IsSplat =
true;
13946 EVT TargetVT =
N->getValueType(0);
13947 for (
int i = 0,
e =
N->getNumOperands(); i <
e; ++i) {
13948 SDValue NextOp =
N->getOperand(i);
13952 if (NextConversion != FirstConversion)
13960 if (
N->getOperand(i) != FirstInput)
13971 for (
int i = 0,
e =
N->getNumOperands(); i <
e; ++i) {
13972 SDValue In =
N->getOperand(i).getOperand(0);
13997 return DAG.
getNode(Opcode, dl, TargetVT, BV);
14010 "Should be called with a BUILD_VECTOR node");
14015 if (!
N->getValueType(0).getVectorElementType().isByteSized())
14018 bool InputsAreConsecutiveLoads =
true;
14019 bool InputsAreReverseConsecutive =
true;
14020 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
14021 SDValue FirstInput =
N->getOperand(0);
14022 bool IsRoundOfExtLoad =
false;
14031 N->getNumOperands() == 1)
14034 for (
int i = 1,
e =
N->getNumOperands(); i <
e; ++i) {
14036 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
14039 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
14045 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
14046 LoadSDNode *LD1 = dyn_cast<LoadSDNode>(PreviousInput);
14047 LoadSDNode *LD2 = dyn_cast<LoadSDNode>(NextInput);
14054 InputsAreConsecutiveLoads =
false;
14056 InputsAreReverseConsecutive =
false;
14059 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
14063 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
14064 "The loads cannot be both consecutive and reverse consecutive.");
14067 IsRoundOfExtLoad ? FirstInput.
getOperand(0) : FirstInput;
14069 IsRoundOfExtLoad ?
N->getOperand(
N->getNumOperands()-1).getOperand(0) :
14070 N->getOperand(
N->getNumOperands()-1);
14072 LoadSDNode *LD1 = dyn_cast<LoadSDNode>(FirstLoadOp);
14074 if (InputsAreConsecutiveLoads) {
14075 assert(LD1 &&
"Input needs to be a LoadSDNode.");
14080 if (InputsAreReverseConsecutive) {
14081 assert(
LDL &&
"Input needs to be a LoadSDNode.");
14083 LDL->getBasePtr(),
LDL->getPointerInfo(),
14084 LDL->getAlignment());
14086 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
14090 DAG.
getUNDEF(
N->getValueType(0)), Ops);
14109 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14111 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
14113 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
14114 CorrectElems = CorrectElems >> 8;
14115 Elems = Elems >> 8;
14122 EVT VT =
N->getValueType(0);
14160 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
14180 if (Input && Input != Extract.
getOperand(0))
14186 Elems = Elems << 8;
14195 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14196 if (!isSExtOfVecExtract(
N->getOperand(i))) {
14203 int TgtElemArrayIdx;
14205 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
14206 if (InputSize + OutputSize == 40)
14207 TgtElemArrayIdx = 0;
14208 else if (InputSize + OutputSize == 72)
14209 TgtElemArrayIdx = 1;
14210 else if (InputSize + OutputSize == 48)
14211 TgtElemArrayIdx = 2;
14212 else if (InputSize + OutputSize == 80)
14213 TgtElemArrayIdx = 3;
14214 else if (InputSize + OutputSize == 96)
14215 TgtElemArrayIdx = 4;
14219 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
14221 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
14222 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
14223 if (Elems != CorrectElems) {
14242 SDValue Operand =
N->getOperand(0);
14248 auto *
LD = cast<LoadSDNode>(Operand);
14257 if (!ValidLDType ||
14263 LD->getChain(),
LD->getBasePtr(),
14272 DAGCombinerInfo &DCI)
const {
14274 "Should be called with a BUILD_VECTOR node");
14279 if (!Subtarget.
hasVSX())
14285 SDValue FirstInput =
N->getOperand(0);
14287 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
14302 if (Subtarget.
hasP9Altivec() && !DCI.isBeforeLegalize()) {
14328 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
14332 SDValue Ext2 =
N->getOperand(1).getOperand(0);
14339 if (!Ext1Op || !Ext2Op)
14348 if (FirstElem == 0 && SecondElem == 1)
14350 else if (FirstElem == 2 && SecondElem == 3)
14363 DAGCombinerInfo &DCI)
const {
14366 "Need an int -> FP conversion node here");
14379 if (!
Op.getOperand(0).getValueType().isSimple())
14381 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(
MVT::i1) ||
14382 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(
MVT::i64))
14385 SDValue FirstOperand(
Op.getOperand(0));
14386 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
14387 (FirstOperand.getValueType() ==
MVT::i8 ||
14388 FirstOperand.getValueType() ==
MVT::i16);
14391 bool DstDouble =
Op.getValueType() ==
MVT::f64;
14392 unsigned ConvOp =
Signed ?
14398 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
14406 SDValue ExtOps[] = { Ld, WidthConst };
14418 if (
Op.getOperand(0).getValueType() ==
MVT::i32)
14422 "UINT_TO_FP is supported only with FPCVT");
14440 SDValue Src =
Op.getOperand(0).getOperand(0);
14441 if (Src.getValueType() ==
MVT::f32) {
14443 DCI.AddToWorklist(Src.getNode());
14444 }
else if (Src.getValueType() !=
MVT::f64) {
14459 DCI.AddToWorklist(
FP.getNode());
14478 switch (
N->getOpcode()) {
14483 Chain =
LD->getChain();
14484 Base =
LD->getBasePtr();
14485 MMO =
LD->getMemOperand();
14504 MVT VecTy =
N->getValueType(0).getSimpleVT();
14519 Chain =
Load.getValue(1);
14547 switch (
N->getOpcode()) {
14552 Chain =
ST->getChain();
14553 Base =
ST->getBasePtr();
14554 MMO =
ST->getMemOperand();
14574 SDValue Src =
N->getOperand(SrcOpnd);
14575 MVT VecTy = Src.getValueType().getSimpleVT();
14597 StoreOps, VecTy, MMO);
14604 DAGCombinerInfo &DCI)
const {
14608 unsigned Opcode =
N->getOperand(1).getOpcode();
14611 &&
"Not a FP_TO_INT Instruction!");
14613 SDValue Val =
N->getOperand(1).getOperand(0);
14614 EVT Op1VT =
N->getOperand(1).getValueType();
14621 bool ValidTypeForStoreFltAsInt =
14629 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
14635 DCI.AddToWorklist(Val.
getNode());
14643 Val = DAG.
getNode(ConvOpcode,
14645 DCI.AddToWorklist(Val.
getNode());
14649 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
14655 cast<StoreSDNode>(
N)->getMemoryVT(),
14656 cast<StoreSDNode>(
N)->getMemOperand());
14658 DCI.AddToWorklist(Val.
getNode());
14665 bool PrevElemFromFirstVec =
Mask[0] < NumElts;
14666 for (
int i = 1,
e =
Mask.size(); i <
e; i++) {
14667 if (PrevElemFromFirstVec &&
Mask[i] < NumElts)
14669 if (!PrevElemFromFirstVec &&
Mask[i] >= NumElts)
14671 PrevElemFromFirstVec = !PrevElemFromFirstVec;
14682 for (
int i = 0,
e =
Op.getNumOperands(); i <
e; i++) {
14683 FirstOp =
Op.getOperand(i);
14689 for (
int i = 1,
e =
Op.getNumOperands(); i <
e; i++)
14690 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
14700 Op =
Op.getOperand(0);
14715 int LHSMaxIdx,
int RHSMinIdx,
14716 int RHSMaxIdx,
int HalfVec,
14717 unsigned ValidLaneWidth,
14719 for (
int i = 0,
e = ShuffV.
size(); i <
e; i++) {
14720 int Idx = ShuffV[i];
14721 if ((Idx >= 0 && Idx < LHSMaxIdx) || (Idx >= RHSMinIdx && Idx < RHSMaxIdx))
14723 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - ValidLaneWidth;
14734 SDLoc dl(OrigSToV);
14737 "Expecting a SCALAR_TO_VECTOR here");
14750 "Cannot produce a permuted scalar_to_vector for one element vector");
14752 unsigned ResultInElt = NumElts / 2;
14779 int NumElts =
LHS.getValueType().getVectorNumElements();
14799 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
14808 if (SToVLHS || SToVRHS) {
14811 int NumEltsOut = ShuffV.
size();
14816 unsigned ValidLaneWidth =
14818 LHS.getValueType().getScalarSizeInBits()
14820 RHS.getValueType().getScalarSizeInBits();
14824 int LHSMaxIdx = -1;
14825 int RHSMinIdx = -1;
14826 int RHSMaxIdx = -1;
14827 int HalfVec =
LHS.getValueType().getVectorNumElements() / 2;
14839 LHSMaxIdx = NumEltsOut / NumEltsIn;
14848 RHSMinIdx = NumEltsOut;
14849 RHSMaxIdx = NumEltsOut / NumEltsIn + RHSMinIdx;
14862 HalfVec, ValidLaneWidth, Subtarget);
14867 if (!isa<ShuffleVectorSDNode>(Res))
14869 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
14888 if (IsLittleEndian) {
14891 if (
Mask[0] < NumElts)
14892 for (
int i = 1,
e =
Mask.size(); i <
e; i += 2)
14893 ShuffV[i] = (ShuffV[i - 1] + NumElts);
14897 for (
int i = 0,
e =
Mask.size(); i <
e; i += 2)
14898 ShuffV[i] = (ShuffV[i + 1] + NumElts);
14902 if (
Mask[0] < NumElts)
14903 for (
int i = 0,
e =
Mask.size(); i <
e; i += 2)
14904 ShuffV[i] = ShuffV[i + 1] - NumElts;
14908 for (
int i = 1,
e =
Mask.size(); i <
e; i += 2)
14909 ShuffV[i] = ShuffV[i - 1] - NumElts;
14915 cast<BuildVectorSDNode>(TheSplat.
getNode())->getSplatValue();
14918 if (IsLittleEndian)
14927 DAGCombinerInfo &DCI)
const {
14929 "Not a reverse memop pattern!");
14934 auto I =
Mask.rbegin();
14935 auto E =
Mask.rend();
14937 for (;
I !=
E; ++
I) {
14957 if(!IsElementReverse(SVN))
14998 switch (
N->getOpcode()) {
15001 return combineADD(
N, DCI);
15003 return combineSHL(
N, DCI);
15005 return combineSRA(
N, DCI);
15007 return combineSRL(
N, DCI);
15009 return combineMUL(
N, DCI);
15012 return combineFMALike(
N, DCI);
15015 return N->getOperand(0);
15019 return N->getOperand(0);
15025 return N->getOperand(0);
15031 return DAGCombineExtBoolTrunc(
N, DCI);
15033 return combineTRUNCATE(
N, DCI);
15035 if (
SDValue CSCC = combineSetCC(
N, DCI))
15039 return DAGCombineTruncBoolExt(
N, DCI);
15042 return combineFPToIntToFP(
N, DCI);
15045 LSBaseSDNode* LSBase = cast<LSBaseSDNode>(
N->getOperand(0));
15046 return combineVReverseMemOP(cast<ShuffleVectorSDNode>(
N), LSBase, DCI);
15048 return combineVectorShuffle(cast<ShuffleVectorSDNode>(
N), DCI.
DAG);
15051 EVT Op1VT =
N->getOperand(1).getValueType();
15052 unsigned Opcode =
N->getOperand(1).getOpcode();
15055 SDValue Val= combineStoreFPToInt(
N, DCI);
15062 SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(
N), DCI);
15068 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
15069 N->getOperand(1).getNode()->hasOneUse() &&
15075 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
15079 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
15086 if (Op1VT.
bitsGT(mVT)) {
15096 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
15100 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
15101 cast<StoreSDNode>(
N)->getMemOperand());
15107 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT ==
MVT::i32) {
15109 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
15119 cast<StoreSDNode>(
N)->setTruncatingStore(
true);
15136 EVT VT =
LD->getValueType(0);
15155 auto ReplaceTwoFloatLoad = [&]() {
15171 if (!
LD->hasNUsesOfValue(2, 0))
15174 auto UI =
LD->use_begin();
15175 while (UI.getUse().getResNo() != 0) ++UI;
15177 while (UI.getUse().getResNo() != 0) ++UI;
15178 SDNode *RightShift = *UI;
15186 if (RightShift->getOpcode() !=
ISD::SRL ||
15187 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
15188 RightShift->getConstantOperandVal(1) != 32 ||
15189 !RightShift->hasOneUse())
15192 SDNode *Trunc2 = *RightShift->use_begin();
15215 if (
LD->isIndexed()) {
15217 "Non-pre-inc AM on PPC?");
15226 LD->getPointerInfo(),
LD->getAlignment(),
15227 MMOFlags,
LD->getAAInfo());
15233 LD->getPointerInfo().getWithOffset(4),
15234 MinAlign(
LD->getAlignment(), 4), MMOFlags,
LD->getAAInfo());
15236 if (
LD->isIndexed()) {
15250 if (ReplaceTwoFloatLoad())
15253 EVT MemVT =
LD->getMemoryVT();
15262 LD->getAlign() < ABIAlignment) {
15293 MVT PermCntlTy, PermTy, LDTy;
15294 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
15295 : Intrinsic::ppc_altivec_lvsl;
15296 IntrLD = Intrinsic::ppc_altivec_lvx;
15297 IntrPerm = Intrinsic::ppc_altivec_vperm;
15318 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
15322 BaseLoadOps, LDTy, BaseMMO);
15331 int IncValue = IncOffset;
15348 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
15352 ExtraLoadOps, LDTy, ExtraMMO);
15363 if (isLittleEndian)
15365 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
15368 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
15387 unsigned IID = cast<ConstantSDNode>(
N->getOperand(0))->getZExtValue();
15389 : Intrinsic::ppc_altivec_lvsl);
15390 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
15397 .
zext(Add.getScalarValueSizeInBits()))) {
15398 SDNode *BasePtr = Add->getOperand(0).getNode();
15399 for (
SDNode *U : BasePtr->uses()) {
15401 cast<ConstantSDNode>(U->getOperand(0))->getZExtValue() == IID) {
15411 if (isa<ConstantSDNode>(Add->getOperand(1))) {
15412 SDNode *BasePtr = Add->getOperand(0).getNode();
15413 for (
SDNode *U : BasePtr->uses()) {
15415 isa<ConstantSDNode>(U->getOperand(1)) &&
15416 (cast<ConstantSDNode>(Add->getOperand(1))->getZExtValue() -
15417 cast<ConstantSDNode>(U->getOperand(1))->getZExtValue()) %
15423 cast<ConstantSDNode>(V->getOperand(0))->getZExtValue() ==
15436 (IID == Intrinsic::ppc_altivec_vmaxsw ||
15437 IID == Intrinsic::ppc_altivec_vmaxsh ||
15438 IID == Intrinsic::ppc_altivec_vmaxsb)) {
15454 V2.getOperand(1) == V1) {
15472 switch (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue()) {
15475 case Intrinsic::ppc_vsx_lxvw4x:
15476 case Intrinsic::ppc_vsx_lxvd2x:
15485 switch (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue()) {
15488 case Intrinsic::ppc_vsx_stxvw4x:
15489 case Intrinsic::ppc_vsx_stxvd2x:
15498 bool Is64BitBswapOn64BitTgt =
15501 N->getOperand(0).hasOneUse();
15502 if (IsSingleUseNormalLd &&
15504 (Subtarget.
hasLDBRX() && Is64BitBswapOn64BitTgt))) {
15517 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
15538 !IsSingleUseNormalLd)
15543 if (!
LD->isSimple())
15547 LD->getPointerInfo(),
LD->getAlignment());
15552 LD->getMemOperand(), 4, 4);
15562 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
15571 if (!
N->getOperand(0).hasOneUse() &&
15572 !
N->getOperand(1).hasOneUse() &&
15573 !
N->getOperand(2).hasOneUse()) {
15576 SDNode *VCMPrecNode =
nullptr;
15578 SDNode *LHSN =
N->getOperand(0).getNode();
15582 UI->getOperand(1) ==
N->getOperand(1) &&
15583 UI->getOperand(2) ==
N->getOperand(2) &&
15584 UI->getOperand(0) ==
N->getOperand(0)) {
15597 SDNode *FlagUser =
nullptr;
15599 FlagUser ==
nullptr; ++UI) {
15600 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
15613 return SDValue(VCMPrecNode, 0);
15621 cast<ConstantSDNode>(
Cond.getOperand(1))->getZExtValue() ==
15622 Intrinsic::loop_decrement) {
15628 "Counter decrement has more than one use");
15640 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(1))->get();
15647 cast<ConstantSDNode>(
LHS.getOperand(0).getOperand(1))->getZExtValue() ==
15648 Intrinsic::loop_decrement &&
15649 isa<ConstantSDNode>(
LHS.getOperand(1)) &&
15651 LHS =
LHS.getOperand(0);
15654 cast<ConstantSDNode>(
LHS.getOperand(1))->getZExtValue() ==
15655 Intrinsic::loop_decrement &&
15656 isa<ConstantSDNode>(
RHS)) {
15658 "Counter decrement comparison is not EQ or NE");
15660 unsigned Val = cast<ConstantSDNode>(
RHS)->getZExtValue();
15668 "Counter decrement has more than one use");
15671 N->getOperand(0),
N->getOperand(4));
15680 assert(isDot &&
"Can't compare against a vector result!");
15684 unsigned Val = cast<ConstantSDNode>(
RHS)->getZExtValue();
15685 if (Val != 0 && Val != 1) {
15687 return N->getOperand(0);
15690 N->getOperand(0),
N->getOperand(4));
15693 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
15706 switch (cast<ConstantSDNode>(
LHS.getOperand(1))->getZExtValue()) {
15725 N->getOperand(4), CompNode.
getValue(1));
15730 return DAGCombineBuildVector(
N, DCI);
15732 return combineABS(
N, DCI);
15734 return combineVSelect(
N, DCI);
15745 EVT VT =
N->getValueType(0);
15776 const APInt &DemandedElts,
15778 unsigned Depth)
const {
15780 switch (
Op.getOpcode()) {
15784 if (cast<VTSDNode>(
Op.getOperand(2))->getVT() ==
MVT::i16)
15785 Known.
Zero = 0xFFFF0000;
15789 switch (cast<ConstantSDNode>(
Op.getOperand(0))->getZExtValue()) {
15791 case Intrinsic::ppc_altivec_vcmpbfp_p:
15792 case Intrinsic::ppc_altivec_vcmpeqfp_p:
15793 case Intrinsic::ppc_altivec_vcmpequb_p:
15794 case Intrinsic::ppc_altivec_vcmpequh_p:
15795 case Intrinsic::ppc_altivec_vcmpequw_p:
15796 case Intrinsic::ppc_altivec_vcmpequd_p:
15797 case Intrinsic::ppc_altivec_vcmpequq_p:
15798 case Intrinsic::ppc_altivec_vcmpgefp_p:
15799 case Intrinsic::ppc_altivec_vcmpgtfp_p:
15800 case Intrinsic::ppc_altivec_vcmpgtsb_p:
15801 case Intrinsic::ppc_altivec_vcmpgtsh_p:
15802 case Intrinsic::ppc_altivec_vcmpgtsw_p:
15803 case Intrinsic::ppc_altivec_vcmpgtsd_p:
15804 case Intrinsic::ppc_altivec_vcmpgtsq_p:
15805 case Intrinsic::ppc_altivec_vcmpgtub_p:
15806 case Intrinsic::ppc_altivec_vcmpgtuh_p:
15807 case Intrinsic::ppc_altivec_vcmpgtuw_p:
15808 case Intrinsic::ppc_altivec_vcmpgtud_p:
15809 case Intrinsic::ppc_altivec_vcmpgtuq_p:
15816 switch (cast<ConstantSDNode>(
Op.getOperand(1))->getZExtValue()) {
15819 case Intrinsic::ppc_load2r:
15821 Known.
Zero = 0xFFFF0000;
15861 for (
auto J = (*I)->begin(), JE = (*I)->end(); J != JE; ++J) {
15862 LoopSize +=
TII->getInstSizeInBytes(*J);
15867 if (LoopSize > 16 && LoopSize <= 32)
15881 if (Constraint.
size() == 1) {
15882 switch (Constraint[0]) {
15900 }
else if (Constraint ==
"wc") {
15902 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
15903 Constraint ==
"wf" || Constraint ==
"ws" ||
15904 Constraint ==
"wi" || Constraint ==
"ww") {
15917 Value *CallOperandVal =
info.CallOperandVal;
15920 if (!CallOperandVal)
15927 else if ((
StringRef(constraint) ==
"wa" ||
15939 switch (*constraint) {
15969 std::pair<unsigned, const TargetRegisterClass *>
15973 if (Constraint.
size() == 1) {
15975 switch (Constraint[0]) {
15978 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
15979 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
15982 return std::make_pair(0U, &PPC::G8RCRegClass);
15983 return std::make_pair(0U, &PPC::GPRCRegClass);
15989 if (Subtarget.
hasSPE()) {
15991 return std::make_pair(0U, &PPC::GPRCRegClass);
15993 return std::make_pair(0U, &PPC::SPERCRegClass);
15996 return std::make_pair(0U, &PPC::F4RCRegClass);
15998 return std::make_pair(0U, &PPC::F8RCRegClass);
16003 return std::make_pair(0U, &PPC::VRRCRegClass);
16004 else if (Subtarget.
hasVSX())
16006 return std::make_pair(0U, &PPC::VFRCRegClass);
16009 return std::make_pair(0U, &PPC::CRRCRegClass);
16011 }
else if (Constraint ==
"wc" && Subtarget.
useCRBits()) {
16013 return std::make_pair(0U, &PPC::CRBITRCRegClass);
16014 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
16015 Constraint ==
"wf" || Constraint ==
"wi") &&
16020 return std::make_pair(0U, &PPC::VSRCRegClass);
16022 return std::make_pair(0U, &PPC::VSSRCRegClass);
16023 return std::make_pair(0U, &PPC::VSFRCRegClass);
16024 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.
hasVSX()) {
16026 return std::make_pair(0U, &PPC::VSSRCRegClass);
16028 return std::make_pair(0U, &PPC::VSFRCRegClass);
16029 }
else if (Constraint ==
"lr") {
16031 return std::make_pair(0U, &PPC::LR8RCRegClass);
16033 return std::make_pair(0U, &PPC::LRRCRegClass);
16038 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
16042 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
16043 int VSNum = atoi(Constraint.
data() + 3);
16044 assert(VSNum >= 0 && VSNum <= 63 &&
16045 "Attempted to access a vsr out of range");
16047 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
16048 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
16053 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
16054 int RegNum = atoi(Constraint.
data() + 2);
16055 if (RegNum > 31 || RegNum < 0)
16058 return Subtarget.
hasSPE()
16059 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
16060 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
16062 return Subtarget.
hasSPE()
16063 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
16064 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
16068 std::pair<unsigned, const TargetRegisterClass *> R =
16078 PPC::GPRCRegClass.contains(R.first))
16079 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
16080 PPC::sub_32, &PPC::G8RCRegClass),
16081 &PPC::G8RCRegClass);
16084 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
16085 R.first = PPC::CR0;
16086 R.second = &PPC::CRRCRegClass;
16090 if (Subtarget.
isAIXABI() && !
TM.getAIXExtendedAltivecABI()) {
16091 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
16092 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
16093 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
16094 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
16095 "default AIX AltiVec ABI and cannot be used\n";
16104 std::string &Constraint,
16105 std::vector<SDValue>&Ops,
16110 if (Constraint.length() > 1)
return;
16112 char Letter = Constraint[0];
16136 if (isShiftedUInt<16, 16>(
Value))
16140 if (isShiftedInt<16, 16>(
Value))
16168 if (Result.getNode()) {
16169 Ops.push_back(Result);
16201 switch (AM.
Scale) {
16232 unsigned Depth = cast<ConstantSDNode>(
Op.getOperand(0))->getZExtValue();
16238 bool isPPC64 = Subtarget.
isPPC64();
16257 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
16265 unsigned Depth = cast<ConstantSDNode>(
Op.getOperand(0))->getZExtValue();
16278 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
16280 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
16294 bool isPPC64 = Subtarget.
isPPC64();
16328 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
16346 unsigned Intrinsic)
const {
16347 switch (Intrinsic) {
16348 case Intrinsic::ppc_atomicrmw_xchg_i128:
16349 case Intrinsic::ppc_atomicrmw_add_i128:
16350 case Intrinsic::ppc_atomicrmw_sub_i128:
16351 case Intrinsic::ppc_atomicrmw_nand_i128:
16352 case Intrinsic::ppc_atomicrmw_and_i128:
16353 case Intrinsic::ppc_atomicrmw_or_i128:
16354 case Intrinsic::ppc_atomicrmw_xor_i128:
16355 case Intrinsic::ppc_cmpxchg_i128:
16358 Info.ptrVal =
I.getArgOperand(0);
16364 case Intrinsic::ppc_atomic_load_i128:
16367 Info.ptrVal =
I.getArgOperand(0);
16372 case Intrinsic::ppc_atomic_store_i128:
16375 Info.ptrVal =
I.getArgOperand(2);
16380 case Intrinsic::ppc_altivec_lvx:
16381 case Intrinsic::ppc_altivec_lvxl:
16382 case Intrinsic::ppc_altivec_lvebx:
16383 case Intrinsic::ppc_altivec_lvehx:
16384 case Intrinsic::ppc_altivec_lvewx:
16385 case Intrinsic::ppc_vsx_lxvd2x:
16386 case Intrinsic::ppc_vsx_lxvw4x:
16387 case Intrinsic::ppc_vsx_lxvd2x_be:
16388 case Intrinsic::ppc_vsx_lxvw4x_be:
16389 case Intrinsic::ppc_vsx_lxvl:
16390 case Intrinsic::ppc_vsx_lxvll: {
16392 switch (Intrinsic) {
16393 case Intrinsic::ppc_altivec_lvebx:
16396 case Intrinsic::ppc_altivec_lvehx:
16399 case Intrinsic::ppc_altivec_lvewx:
16402 case Intrinsic::ppc_vsx_lxvd2x:
16403 case Intrinsic::ppc_vsx_lxvd2x_be:
16413 Info.ptrVal =
I.getArgOperand(0);
16420 case Intrinsic::ppc_altivec_stvx:
16421 case Intrinsic::ppc_altivec_stvxl:
16422 case Intrinsic::ppc_altivec_stvebx:
16423 case Intrinsic::ppc_altivec_stvehx:
16424 case Intrinsic::ppc_altivec_stvewx:
16425 case Intrinsic::ppc_vsx_stxvd2x:
16426 case Intrinsic::ppc_vsx_stxvw4x:
16427 case Intrinsic::ppc_vsx_stxvd2x_be:
16428 case Intrinsic::ppc_vsx_stxvw4x_be:
16429 case Intrinsic::ppc_vsx_stxvl:
16430 case Intrinsic::ppc_vsx_stxvll: {
16432 switch (Intrinsic) {
16433 case Intrinsic::ppc_altivec_stvebx:
16436 case Intrinsic::ppc_altivec_stvehx:
16439 case Intrinsic::ppc_altivec_stvewx:
16442 case Intrinsic::ppc_vsx_stxvd2x:
16443 case Intrinsic::ppc_vsx_stxvd2x_be:
16453 Info.ptrVal =
I.getArgOperand(1);
16494 return !(BitSize == 0 || BitSize > 64);
16502 return NumBits1 == 64 && NumBits2 == 32;
16510 return NumBits1 == 64 && NumBits2 == 32;
16517 EVT MemVT =
LD->getMemoryVT();
16535 "invalid fpext types");
16552 bool *Fast)
const {
16570 if (Subtarget.
hasVSX()) {
16593 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
16594 if (!ConstNode->getAPIntValue().isSignedIntN(64))
16602 int64_t Imm = ConstNode->getSExtValue();
16603 unsigned Shift = countTrailingZeros<uint64_t>(Imm);
16636 if (!
I->hasOneUse())
16640 assert(
User &&
"A single use instruction with no uses.");
16642 switch (
I->getOpcode()) {
16643 case Instruction::FMul: {
16645 if (
User->getOpcode() != Instruction::FSub &&
16646 User->getOpcode() != Instruction::FAdd)
16692 static const MCPhysReg ScratchRegs[] = {
16693 PPC::X12, PPC::LR8, PPC::CTR8, 0
16696 return ScratchRegs;
16700 const Constant *PersonalityFn)
const {
16701 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
16705 const Constant *PersonalityFn)
const {
16711 EVT VT ,
unsigned DefinedValues)
const {
16749 bool LegalOps,
bool OptForSize,
16751 unsigned Depth)
const {
16755 unsigned Opc =
Op.getOpcode();
16756 EVT VT =
Op.getValueType();
16785 N0Cost,
Depth + 1);
16789 N1Cost,
Depth + 1);
16791 if (NegN0 && N0Cost <= N1Cost) {
16793 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
16794 }
else if (NegN1) {
16796 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
16839 bool ForCodeSize)
const {
16868 unsigned Opcode =
N->getOpcode();
16869 unsigned TargetOpcode;
16888 if (
Mask->getZExtValue() == OpSizeInBits - 1)
16894 SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
16924 SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
16931 SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
16950 auto isZextOfCompareWithConstant = [](
SDValue Op) {
16956 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
16957 Cmp.getOperand(0).getValueType() !=
MVT::i64)
16960 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
16961 int64_t NegConstant = 0 -
Constant->getSExtValue();
16970 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
16971 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
16974 if (LHSHasPattern && !RHSHasPattern)
16976 else if (!LHSHasPattern && !RHSHasPattern)
16982 SDValue Z = Cmp.getOperand(0);
16983 auto *
Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
16984 int64_t NegConstant = 0 -
Constant->getSExtValue();
16986 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
16997 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
17012 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
17049 if (!GSDN || !ConstNode)
17056 if (!isInt<34>(NewOffset))
17069 SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17089 DAGCombinerInfo &DCI)
const {
17093 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
17094 return CRTruncValue;
17102 EVT VT =
N->getValueType(0);
17113 DCI.DAG.getTargetConstant(0, dl,
MVT::i32));
17122 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
17132 EltToExtract = EltToExtract ? 0 : 1;
17142 return DCI.DAG.getNode(
17144 DCI.DAG.getTargetConstant(EltToExtract, dl,
MVT::i32));
17149 SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17153 if (!ConstOpOrElement)
17161 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
17184 return IsAddOne && IsNeg ? VT.
isVector() :
true;
17188 EVT VT =
N->getValueType(0);
17195 if ((MulAmtAbs - 1).isPowerOf2()) {
17199 if (!IsProfitable(IsNeg,
true, VT))
17212 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
17216 if (!IsProfitable(IsNeg,
false, VT))
17237 DAGCombinerInfo &DCI)
const {
17242 EVT VT =
N->getValueType(0);
17245 unsigned Opc =
N->getOpcode();
17247 bool LegalOps = !DCI.isBeforeLegalizeOps();
17271 bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
17288 if (!Callee ||
Callee->isVarArg())
17301 bool PPCTargetLowering::hasBitPreservingFPLogic(
EVT VT)
const {
17302 if (!Subtarget.
hasVSX())
17310 bool PPCTargetLowering::
17311 isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
17316 if (CI->getBitWidth() > 64)
17318 int64_t ConstVal = CI->getZExtValue();
17320 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
17332 SDValue PPCTargetLowering::combineABS(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17335 "Only combine this when P9 altivec supported!");
17336 EVT VT =
N->getValueType(0);
17342 if (
N->getOperand(0).getOpcode() ==
ISD::SUB) {
17345 unsigned SubOpcd0 =
N->getOperand(0)->getOperand(0).getOpcode();
17346 unsigned SubOpcd1 =
N->getOperand(0)->getOperand(1).getOpcode();
17352 N->getOperand(0)->getOperand(0),
17353 N->getOperand(0)->getOperand(1),
17358 if (
N->getOperand(0).getValueType() ==
MVT::v4i32 &&
17359 N->getOperand(0).hasOneUse()) {
17361 N->getOperand(0)->getOperand(0),
17362 N->getOperand(0)->getOperand(1),
17376 DAGCombinerInfo &DCI)
const {
17379 "Only combine this when P9 altivec supported!");
17384 SDValue TrueOpnd =
N->getOperand(1);
17385 SDValue FalseOpnd =
N->getOperand(2);
17386 EVT VT =
N->getOperand(1).getValueType();
17426 CmpOpnd1, CmpOpnd2,
17435 PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
17441 if ((Flags & FlagSet) == FlagSet)
17444 if ((Flags & FlagSet) == FlagSet)
17447 if ((Flags & FlagSet) == FlagSet)
17450 if ((Flags & FlagSet) == FlagSet)
17471 if ((FrameIndexAlign % 4) != 0)
17473 if ((FrameIndexAlign % 16) != 0)
17478 if ((FrameIndexAlign % 4) == 0)
17480 if ((FrameIndexAlign % 16) == 0)
17493 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
17494 if ((Imm & 0x3) == 0)
17496 if ((Imm & 0xf) == 0)
17502 const APInt &ConstImm = CN->getAPIntValue();
17521 const APInt &ConstImm = CN->getAPIntValue();
17532 !cast<ConstantSDNode>(
RHS.getOperand(1))->getZExtValue())
17544 isValidPCRelNode<ConstantPoolSDNode>(
N) ||
17545 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
17546 isValidPCRelNode<JumpTableSDNode>(
N) ||
17547 isValidPCRelNode<BlockAddressSDNode>(
N));
17552 unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
17573 unsigned ParentOp = Parent->
getOpcode();
17576 unsigned ID = cast<ConstantSDNode>(Parent->
getOperand(1))->getZExtValue();
17577 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
17578 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
17589 if (
const LSBaseSDNode *LSB = dyn_cast<LSBaseSDNode>(Parent))
17590 if (LSB->isIndexed())
17595 const MemSDNode *MN = dyn_cast<MemSDNode>(Parent);
17596 assert(MN &&
"Parent should be a MemSDNode!");
17601 "Not expecting scalar integers larger than 16 bytes!");
17604 else if (
Size == 32)
17611 else if (
Size == 256) {
17613 "256-bit vectors are only available when paired vector memops is "
17631 if (
const LoadSDNode *LN = dyn_cast<LoadSDNode>(Parent)) {
17657 bool IsNonP1034BitConst =
17661 IsNonP1034BitConst)
17674 int16_t ForceXFormImm = 0;
17677 Disp =
N.getOperand(0);
17678 Base =
N.getOperand(1);
17689 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
17690 Disp =
N.getOperand(0);
17691 Base =
N.getOperand(1);
17725 if (!isa<FrameIndexSDNode>(
N))
17743 unsigned Flags = computeMOFlags(Parent,
N, DAG);
17755 "Must be using PC-Relative calls when a valid PC-Relative node is "
17771 int16_t Imm = cast<ConstantSDNode>(Op1)->getAPIntValue().getZExtValue();
17785 Disp =
N.getOperand(1).getOperand(0);
17790 Base =
N.getOperand(0);
17797 auto *CN = cast<ConstantSDNode>(
N);
17798 EVT CNType = CN->getValueType(0);
17799 uint64_t CNImm = CN->getZExtValue();
17812 int32_t
Addr = (int32_t)CNImm;
17817 uint32_t LIS = CNType ==
MVT::i32 ? PPC::LIS : PPC::LIS8;
17833 unsigned Opcode =
N.getOpcode();
17841 Base =
N.getOperand(0);
17860 Base = FI ?
N :
N.getOperand(1);
17872 bool IsVarArg)
const {
17903 return Intrinsic::ppc_atomicrmw_xchg_i128;
17905 return Intrinsic::ppc_atomicrmw_add_i128;
17907 return Intrinsic::ppc_atomicrmw_sub_i128;
17909 return Intrinsic::ppc_atomicrmw_and_i128;
17911 return Intrinsic::ppc_atomicrmw_or_i128;
17913 return Intrinsic::ppc_atomicrmw_xor_i128;
17915 return Intrinsic::ppc_atomicrmw_nand_i128;
17923 "Only support quadword now");
17924 Module *M =
Builder.GetInsertBlock()->getParent()->getParent();
17930 Value *IncrLo =
Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
17932 Builder.CreateTrunc(
Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
17948 "Only support quadword now");
17949 Module *M =
Builder.GetInsertBlock()->getParent()->getParent();
17955 Value *CmpLo =
Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
17957 Builder.CreateTrunc(
Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
17958 Value *NewLo =
Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
17960 Builder.CreateTrunc(
Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
17965 Builder.CreateCall(IntCmpXchg, {
Addr, CmpLo, CmpHi, NewLo, NewHi});
return AArch64::GPR64RegClass contains(Reg)
unsigned const MachineRegisterInfo * MRI
static const unsigned PerfectShuffleTable[6561+1]
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu Simplify well known AMD library false FunctionCallee Callee
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isLoad(int Opcode)
Function Alias Analysis Results
Atomic ordering constants.
SmallVector< MachineOperand, 4 > Cond
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
Module.h This file contains the declarations for the Module class.
This file provides None, an enumerator for use in implicit constructors of various (usually templated...
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static unsigned getCallOpcode(PPCTargetLowering::CallFlags CFlags, const Function &Caller, const SDValue &Callee, const PPCSubtarget &Subtarget, const TargetMachine &TM, bool IsStrictFPCall=false)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static bool isConstantOrUndef(int Op, int Val)
isConstantOrUndef - Op is either an undef node or a ConstantSDNode.
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static bool callsShareTOCBase(const Function *Caller, SDValue Callee, const TargetMachine &TM)
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool isFunctionGlobalAddress(SDValue Callee)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool isPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static void getBaseWithConstantOffset(SDValue Loc, SDValue &Base, int64_t &Offset, SelectionDAG &DAG)
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &S)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static const char AIXSSPCanaryWordName[]
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InFlag, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static Intrinsic::ID getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSMaxIdx, int RHSMinIdx, int RHSMaxIdx, int HalfVec, unsigned ValidLaneWidth, const PPCSubtarget &Subtarget)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue GeneratePerfectShuffle(unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &dl)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static cl::opt< bool > EnableQuadwordAtomics("ppc-quadword-atomics", cl::desc("enable quadword lock-free atomic operations"), cl::init(false), cl::Hidden)
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static bool isSignExtended(MachineInstr &MI, const PPCInstrInfo *TII)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static int getEstimateRefinementSteps(EVT VT, const PPCSubtarget &Subtarget)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
cl::opt< bool > ANDIGlueBug
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is 0.0 or -0.0.
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
const char LLVMTargetMachineRef TM
ManagedStatic< detail::RecordContext > Context
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
static bool isSplat(ArrayRef< Value * > VL)
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
This file describes how to lower LLVM code to machine code.
This defines the Use class.
static bool is64Bit(const char *name)
bool isFixed(unsigned ValNo) const
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isNegative() const
Determine sign of this APInt.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
This class represents an incoming formal argument to a Function.
size_t size() const
size - Get the array size.
Class to represent array types.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
BinOp getOperation() const
This is an SDNode representing atomic operations.
StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
const BlockAddress * getBlockAddress() const
int64_t getOffset() const
The address of a basic block.
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
MachineFunction & getMachineFunction() const
unsigned AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
unsigned getNextStackOffset() const
getNextStackOffset - Return the next stack offset such that all stack slots satisfy their alignment r...
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
unsigned getLocMemOffset() const
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
unsigned getValNo() const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
uint64_t getZExtValue() const
int64_t getSExtValue() const
const APInt & getAPIntValue() const
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
const GlobalValue * getGlobal() const
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalObject * getAliaseeObject() const
StringRef getSection() const
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
Module * getParent()
Get the module that this global value is contained inside of...
Common base class shared among various IRBuilders.
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag.
@ Kind_RegDefEarlyClobber
static unsigned getKind(unsigned Flags)
const BasicBlock * getParent() const
bool hasAtomicLoad() const
Return true if this atomic instruction loads from memory.
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
const std::vector< LoopT * > & getSubLoops() const
Return the loops contained entirely within this loop.
unsigned getLoopDepth() const
Return the nesting level of this loop.
block_iterator block_end() const
block_iterator block_begin() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
StringRef getName() const
getName - Get the symbol name.
uint64_t getScalarSizeInBits() const
@ INVALID_SIMPLE_VALUE_TYPE
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineModuleInfo & getMMI() const
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
uint64_t getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
const MCContext & getContext() const
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
const SDValue & getChain() const
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
const SDValue & getBasePtr() const
unsigned getAlignment() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
GlobalValue * getNamedValue(StringRef Name) const
Return the global value in the module with the specified name, of arbitrary type.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
uint64_t getFramePointerSaveOffset() const
getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
void setTailCallSPDelta(int size)
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
bool useLongCalls() const
bool is32BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
const PPCFrameLowering * getFrameLowering() const override
unsigned descriptorTOCAnchorOffset() const
bool useSoftFloat() const
bool use64BitRegs() const
use64BitRegs - Return true if in 64-bit mode or if we should use 64-bit registers in 32-bit mode when...
bool allowsUnalignedFPAccess() const
bool needsSwapsForVSXMemOps() const
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
bool needsTwoConstNR() const
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
bool hasQuadwordAtomics() const
const PPCInstrInfo * getInstrInfo() const override
MCRegister getEnvironmentPointerRegister() const
bool useCRBits() const
useCRBits - Return true if we should store and manipulate i1 values in the individual condition regis...
bool hasRecipPrec() const
bool hasInvariantFunctionDescriptors() const
unsigned getCPUDirective() const
getCPUDirective - Returns the -m directive specified for the cpu.
POPCNTDKind hasPOPCNTD() const
bool hasPrefixInstrs() const
bool hasPartwordAtomics() const
bool isLittleEndian() const
bool isTargetLinux() const
bool hasP9Altivec() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
const PPCRegisterInfo * getRegisterInfo() const override
bool has64BitSupport() const
has64BitSupport - Return true if the selected CPU supports 64-bit instructions, regardless of whether...
bool is64BitELFABI() const
bool pairedVectorMemops() const
bool isPredictableSelectIsExpensive() const
bool enableMachineScheduler() const override
Scheduling customization.
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
unsigned descriptorEnvironmentPointerOffset() const
bool hasDirectMove() const
bool hasP8Altivec() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
unsigned getStackProbeSize(MachineFunction &MF) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
const char * getTargetNodeName(unsigned Opcode) const override
getTargetNodeName() - This method returns the name of a target specific DAG node.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, Optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
void insertSSPDeclarations(Module &M) const override
Inserts necessary declarations for SSP (stack protection) purpose.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
uint64_t getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
EVT getOptimalMemOpType(const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool useLoadStackGuardNode() const override
Override to support customized stack guard loading.
bool hasInlineStackProbe(MachineFunction &MF) const override
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=None) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, bool *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
Value * getSDagStackGuard(const Module &M) const override
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
Wrapper class representing virtual and physical registers.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
bool isOnlyUserOf(const SDNode *N) const
Return true if this node is the only use of N.
SDNodeFlags getFlags() const
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
const SDValue & getOperand(unsigned Num) const
ArrayRef< SDUse > ops() const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< use_iterator > uses()
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
op_iterator op_end() const
op_iterator op_begin() const
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS)
Helper function to make it easier to build Select's if you just have operands and don't want to check...
SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=None, int Offset=0, unsigned TargetFlags=0)
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
const TargetSubtargetInfo & getSubtarget() const
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getTargetFrameIndex(int FI, EVT VT)
SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
SDValue getExternalSymbol(const char *Sym, EVT VT)
const DataLayout & getDataLayout() const
MachineFunction & getMachineFunction() const
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
const TargetLowering & getTargetLoweringInfo() const
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, uint64_t Size=0, const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getRegisterMask(const uint32_t *RegMask)
SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
SDValue getCondCode(ISD::CondCode Cond)
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVMContext * getContext() const
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
const TargetMachine & getTarget() const
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
const_iterator begin() const
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
const_iterator end() const
LLVM_NODISCARD bool empty() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
LLVM_NODISCARD T pop_back_val()
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset is a class to represent an offset with 2 dimensions, named fixed and scalable,...
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
std::enable_if_t< std::numeric_limits< T >::is_signed, bool > getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
A switch()-like statement whose cases are string literals.
LLVM_NODISCARD R Default(T Value)
StringSwitch & Case(StringLiteral S, T Value)
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
void setTargetDAGCombine(ISD::NodeType NT)
Targets should invoke this method for each target independent node that they want to provide a custom...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
const TargetMachine & getTargetMachine() const
void setIndexedStoreAction(unsigned IdxMode, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
virtual MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
virtual Value * getSDagStackGuard(const Module &M) const
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
void setCondCodeAction(ISD::CondCode CC, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?...
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL, bool LegalTypes=true) const
Returns the type for the shift amount of a shift opcode.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
virtual AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
NegatibleCost
Enum that specifies when a float negation is beneficial.
std::vector< ArgListEntry > ArgListTy
void setHasMultipleConditionRegisters(bool hasManyRegs=true)
Tells the code generator that the target has multiple (allocatable) condition registers that can be u...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
virtual void insertSSPDeclarations(Module &M) const
Inserts necessary declarations for SSP (stack protection) purpose.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
void setIndexedLoadAction(unsigned IdxMode, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
virtual bool useLoadStackGuardNode() const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Primary interface to the complete machine description for the target machine.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
CodeModel::Model getCodeModel() const
Returns the code model.
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static TypeSize Fixed(ScalarTy MinVal)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
static Type * getVoidTy(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
static IntegerType * getInt64Ty(LLVMContext &C)
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Type * getPointerElementType() const
This method is deprecated without replacement.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
bool hasOneUse() const
Return true if there is exactly one use of this value.
Type * getType() const
All values are typed, get the type of this value.
Base class of all SIMD vector types.
Iterator for intrusive lists based on ilist_node.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Fast
Fast - This calling convention attempts to make calls as fast as possible (e.g.
@ C
C - The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ FLT_ROUNDS_
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val) This corresponds to "store atomic" instruction.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR
Control flow instructions. These all have token chains.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ BR_JT
BR_JT - Jumptable branch.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_GOT_FLAG
MO_GOT_FLAG - If this bit is set the symbol reference is to be computed via the GOT.
@ MO_PLT
On a symbol operand "FOO", this indicates that the reference is actually to "FOO@plt".
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set the symbol reference is relative to TLS Initial Exec model.
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ SEXT_LD_SPLAT
VSRC, CHAIN = SEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that sign-extends.
@ FCTIDUZ
Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for unsigned integers with round ...
@ ADDI_TLSGD_L_ADDR
G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSGD_L and GET_TLS_ADDR unti...
@ FSQRT
Square root instruction.
@ STRICT_FCFID
Constrained integer-to-floating-point conversion instructions.
@ DYNALLOC
The following two target-specific nodes are used for calls through function pointers in the 64-bit SV...
@ COND_BRANCH
CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This corresponds to the COND_BRANCH pseudo ...
@ VABSD
An SDNode for Power9 vector absolute value difference.
@ CALL_RM
The variants that implicitly define rounding mode for calls with strictfp semantics.
@ STORE_VEC_BE
CHAIN = STORE_VEC_BE CHAIN, VSRC, Ptr - Occurs only for little endian.
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
@ MTVSRZ
Direct move from a GPR to a VSX register (zero)
@ SRL
These nodes represent PPC shifts.
@ VECINSERT
VECINSERT - The PPC vector insert instruction.
@ LXSIZX
GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an integer smaller than 64 bits into ...
@ FNMSUB
FNMSUB - Negated multiply-subtract instruction.
@ RFEBB
CHAIN = RFEBB CHAIN, State - Return from event-based branch.
@ FCTIDZ
FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 operand, producing an f64 value...
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ GET_TLS_ADDR
x3 = GET_TLS_ADDR x3, Symbol - For the general-dynamic TLS model, produces a call to __tls_get_addr(s...
@ FP_TO_UINT_IN_VSR
Floating-point-to-interger conversion instructions.
@ XXSPLTI32DX
XXSPLTI32DX - The PPC XXSPLTI32DX instruction.
@ ANDI_rec_1_EQ_BIT
i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after ex...
@ FRE
Reciprocal estimate instructions (unary FP ops).
@ ADDIS_GOT_TPREL_HA
G8RC = ADDIS_GOT_TPREL_HA x2, Symbol - Used by the initial-exec TLS model, produces an ADDIS8 instruc...
@ CLRBHRB
CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer.
@ SINT_VEC_TO_FP
Extract a subvector from signed integer vector and convert to FP.
@ EXTRACT_SPE
Extract SPE register component, second argument is high or low.
@ XXSWAPD
VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little endian.
@ ADDI_TLSLD_L_ADDR
G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSLD_L and GET_TLSLD_ADDR un...
@ ATOMIC_CMP_SWAP_8
ATOMIC_CMP_SWAP - the exact same as the target-independent nodes except they ensure that the compare ...
@ ST_VSR_SCAL_INT
Store scalar integers from VSR.
@ VCMP
RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP* instructions.
@ BCTRL
CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a BCTRL instruction.
@ BUILD_SPE64
BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and EXTRACT_ELEMENT but take f64 arguments in...
@ LFIWZX
GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point load which zero-extends from a 32-bit inte...
@ SCALAR_TO_VECTOR_PERMUTED
PowerPC instructions that have SCALAR_TO_VECTOR semantics tend to place the value into the least sign...
@ EXTRACT_VSX_REG
EXTRACT_VSX_REG = Extract one of the underlying vsx registers of an accumulator or pair register.
@ STXSIX
STXSIX - The STXSI[bh]X instruction.
@ MAT_PCREL_ADDR
MAT_PCREL_ADDR = Materialize a PC Relative address.
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ XXSPLT
XXSPLT - The PPC VSX splat instructions.
@ TOC_ENTRY
GPRC = TOC_ENTRY GA, TOC Loads the entry for GA from the TOC, where the TOC base is given by the last...
@ XXPERMDI
XXPERMDI - The PPC XXPERMDI instruction.
@ ADDIS_DTPREL_HA
G8RC = ADDIS_DTPREL_HA x3, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction t...
@ ADD_TLS
G8RC = ADD_TLS G8RReg, Symbol - Used by the initial-exec TLS model, produces an ADD instruction that ...
@ MTVSRA
Direct move from a GPR to a VSX register (algebraic)
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_GOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ ADDI_DTPREL_L
G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction ...
@ BCTRL_LOAD_TOC
CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl instruction and the TOC reload r...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ FCFID
FCFID - The FCFID instruction, taking an f64 operand and producing and f64 value containing the FP re...
@ CR6SET
ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls
@ LBRX
GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a byte-swapping load instruction.
@ LD_VSX_LH
VSRC, CHAIN = LD_VSX_LH CHAIN, Ptr - This is a floating-point load of a v2f32 value into the lower ha...
@ PROBED_ALLOCA
To avoid stack clash, allocation is performed by block and each block is probed.
@ XXMFACC
XXMFACC = This corresponds to the xxmfacc instruction.
@ ADDIS_TLSGD_HA
G8RC = ADDIS_TLSGD_HA x2, Symbol - For the general-dynamic TLS model, produces an ADDIS8 instruction ...
@ ACC_BUILD
ACC_BUILD = Build an accumulator register from 4 VSX registers.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ LXVD2X
VSRC, CHAIN = LXVD2X_LE CHAIN, Ptr - Occurs only for little endian.
@ CALL
CALL - A direct function call.
@ MTCTR
CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a MTCTR instruction.
@ TC_RETURN
TC_RETURN - A tail call return.
@ STFIWX
STFIWX - The STFIWX instruction.
@ LD_SPLAT
VSRC, CHAIN = LD_SPLAT, CHAIN, Ptr - a splatting load memory instructions such as LXVDSX,...
@ VCMP_rec
RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the altivec VCMP*_rec instructions.
@ MFFS
F8RC = MFFS - This moves the FPSCR (not modeled) into the register.
@ PADDI_DTPREL
G8RC = PADDI_DTPREL x3, Symbol - For the pc-rel based local-dynamic TLS model, produces a PADDI8 inst...
@ BUILD_FP128
Direct move of 2 consecutive GPR to a VSX register.
@ VEXTS
VEXTS, ByteWidth - takes an input in VSFRC and produces an output in VSFRC that is sign-extended from...
@ TLS_LOCAL_EXEC_MAT_ADDR
TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address when using local exec access ...
@ VPERM
VPERM - The PPC VPERM Instruction.
@ ADDIS_TLSLD_HA
G8RC = ADDIS_TLSLD_HA x2, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction th...
@ XXSPLTI_SP_TO_DP
XXSPLTI_SP_TO_DP - The PPC VSX splat instructions for immediates for converting immediate single prec...
@ GET_TLSLD_ADDR
x3 = GET_TLSLD_ADDR x3, Symbol - For the local-dynamic TLS model, produces a call to __tls_get_addr(s...
@ ADDI_TLSGD_L
x3 = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS model, produces an ADDI8 instruction t...
@ DYNAREAOFFSET
This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to compute an offset from native ...
@ PAIR_BUILD
PAIR_BUILD = Build a vector pair register from 2 VSX registers.
@ STRICT_FADDRTZ
Constrained floating point add in round-to-zero mode.
@ FTSQRT
Test instruction for software square root.
@ FP_EXTEND_HALF
FP_EXTEND_HALF(VECTOR, IDX) - Custom extend upper (IDX=0) half or lower (IDX=1) half of v4f32 to v2f6...
@ RET_FLAG
Return with a flag operand, matched by 'blr'.
@ CMPB
The CMPB instruction (takes two operands of i32 or i64).
@ VECSHL
VECSHL - The PPC vector shift left instruction.
@ ADDI_TLSLD_L
x3 = ADDI_TLSLD_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction tha...
@ FADDRTZ
F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding towards zero.
@ ZEXT_LD_SPLAT
VSRC, CHAIN = ZEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that zero-extends.
@ XSMAXCDP
XSMAXCDP, XSMINCDP - C-type min/max instructions.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
@ EXTSWSLI
EXTSWSLI = The PPC extswsli instruction, which does an extend-sign word and shift left immediate.
@ STXVD2X
CHAIN = STXVD2X CHAIN, VSRC, Ptr - Occurs only for little endian.
@ TLSGD_AIX
GPRC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY G8RC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY Op that combines two re...
@ UINT_VEC_TO_FP
Extract a subvector from unsigned integer vector and convert to FP.
@ LXVRZX
LXVRZX - Load VSX Vector Rightmost and Zero Extend This node represents v1i128 BUILD_VECTOR of a zero...
@ MFBHRBE
GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch history rolling buffer entry.
@ FCFIDU
Newer FCFID[US] integer-to-floating-point conversion instructions for unsigned integers and single-pr...
@ FSEL
FSEL - Traditional three-operand fsel node.
@ SWAP_NO_CHAIN
An SDNode for swaps that are not associated with any loads/stores and thereby have no chain.
@ LOAD_VEC_BE
VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian.
@ LFIWAX
GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point load which sign-extends from a 32-bit inte...
@ STBRX
CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a byte-swapping store instruction.
@ LD_GOT_TPREL_L
G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec TLS model, produces a LD instruction ...
@ MFVSR
Direct move from a VSX register to a GPR.
@ TLS_DYNAMIC_MAT_PCREL_ADDR
TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for TLS global address when using dyna...
@ Hi
Hi/Lo - These represent the high and low 16-bit parts of a global address respectively.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
@ Define
Register definition.
Reg
All possible values of the reg field in the ModR/M byte.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
CodeModel::Model getCodeModel()
const_iterator end(StringRef path)
Get end iterator over path.
/file This file defines the SmallVector class.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
static bool isIndirectCall(const MachineInstr &MI)
constexpr bool isUInt< 16 >(uint64_t x)
STATISTIC(NumFunctions, "Total number of functions")
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
bool CC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isInt< 32 >(int64_t x)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
constexpr bool isInt< 16 >(int64_t x)
uint32_t FloatToBits(float Float)
This function takes a float and returns the bit equivalent 32-bit integer.
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
uint64_t PowerOf2Floor(uint64_t A)
Returns the power of two which is less than or equal to the given value.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
unsigned countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1.
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Align max(MaybeAlign Lhs, Align Rhs)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
A and B are either alignments or offsets.
unsigned M0(unsigned Val)
ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr unsigned BitWidth
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Align commonAlignment(Align A, Align B)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble() LLVM_READNONE
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
bool isInConsecutiveRegs() const
unsigned getByValSize() const
bool isInConsecutiveRegsLast() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
bool hasNoSignedZeros() const
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg If BaseGV is null...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
bool isAfterLegalizeDAG() const
void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)